Esempio n. 1
0
/* Translate an OF filesystem path (separated by backslashes), into a GRUB
   path (separated by forward slashes).  */
static void
grub_translate_ieee1275_path (char *filepath)
{
  char *backslash;

  backslash = grub_strchr (filepath, '\\');
  while (backslash != 0)
    {
      *backslash = '/';
      backslash = grub_strchr (filepath, '\\');
    }
}
Esempio n. 2
0
void
grub_machine_init (void)
{
  char args[256];
  grub_ssize_t actual;

  grub_ieee1275_init ();

  grub_console_init_early ();
#ifdef __i386__
  grub_get_extended_memory ();
#endif
  grub_claim_heap ();
  grub_console_init_lately ();
  grub_ofdisk_init ();

  /* Process commandline.  */
  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
				  sizeof args, &actual) == 0
      && actual > 1)
    {
      int i = 0;

      while (i < actual)
	{
	  char *command = &args[i];
	  char *end;
	  char *val;

	  end = grub_strchr (command, ';');
	  if (end == 0)
	    i = actual; /* No more commands after this one.  */
	  else
	    {
	      *end = '\0';
	      i += end - command + 1;
	      while (grub_isspace(args[i]))
		i++;
	    }

	  /* Process command.  */
	  val = grub_strchr (command, '=');
	  if (val)
	    {
	      *val = '\0';
	      grub_env_set (command, val + 1);
	    }
	}
    }

  grub_install_get_time_ms (ieee1275_get_time_ms);
}
Esempio n. 3
0
static grub_err_t
grub_rescue_parse_line (char *line, grub_reader_getline_t getline,
			void *closure)
{
  char *name;
  int n;
  grub_command_t cmd;
  char **args;

  if (grub_parser_split_cmdline (line, getline, closure, &n, &args) || n < 0)
    return grub_errno;

  if (n == 0)
    return GRUB_ERR_NONE;

  /* In case of an assignment set the environment accordingly
     instead of calling a function.  */
  if (n == 1 && grub_strchr (line, '='))
    {
      char *val = grub_strchr (args[0], '=');
      val[0] = 0;
      grub_env_set (args[0], val + 1);
      val[0] = '=';
      goto quit;
    }

  /* Get the command name.  */
  name = args[0];

  /* If nothing is specified, restart.  */
  if (*name == '\0')
    goto quit;

  cmd = grub_command_find (name);
  if (cmd)
    {
      (cmd->func) (cmd, n - 1, &args[1]);
    }
  else
    {
      grub_printf ("Unknown command `%s'\n", name);
      if (grub_command_find ("help"))
	grub_printf ("Try `help' for usage\n");
    }

 quit:
  grub_free (args[0]);
  grub_free (args);

  return grub_errno;
}
Esempio n. 4
0
/* Get the device path of the Open Firmware node name `path'.  */
static char *
grub_ieee1275_get_devname (const char *path)
{
  char *colon = grub_strchr (path, ':');
  char *newpath = 0;
  int pathlen = grub_strlen (path);
  auto int match_alias (struct grub_ieee1275_devalias *alias);

  int match_alias (struct grub_ieee1275_devalias *curalias)
    {
      /* briQ firmware can change capitalization in /chosen/bootpath.  */
      if (! grub_strncasecmp (curalias->path, path, pathlen))
        {
	  newpath = grub_strdup (curalias->name);
	  return 1;
	}

      return 0;
    }

  if (colon)
    pathlen = (int)(colon - path);

  /* Try to find an alias for this device.  */
  grub_devalias_iterate (match_alias);

  if (! newpath)
    newpath = grub_strndup (path, pathlen);

  return newpath;
}
Esempio n. 5
0
/* Helper for match_devices.  */
static int
match_devices_iter (const char *name, void *data)
{
  struct match_devices_ctx *ctx = data;
  char **t;
  char *buffer;

  /* skip partitions if asked to. */
  if (ctx->noparts && grub_strchr (name, ','))
    return 0;

  buffer = grub_xasprintf ("(%s)", name);
  if (! buffer)
    return 1;

  grub_dprintf ("expand", "matching: %s\n", buffer);
  if (regexec (ctx->regexp, buffer, 0, 0, 0))
    {
      grub_dprintf ("expand", "not matched\n");
      grub_free (buffer);
      return 0;
    }

  t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
  if (! t)
    {
      grub_free (buffer);
      return 1;
    }

  ctx->devs = t;
  ctx->devs[ctx->ndev++] = buffer;
  ctx->devs[ctx->ndev] = 0;
  return 0;
}
Esempio n. 6
0
/* Construct a new box widget using ABSPATTERN to find the pixmap files for
   it, storing the new box instance at *BOXPTR.
   PATTERN should be of the form: "(hd0,0)/somewhere/style*.png".
   The '*' then gets substituted with the various pixmap names that the
   box uses.  */
static grub_err_t
recreate_box_absolute (grub_gfxmenu_box_t *boxptr, const char *abspattern)
{
  char *prefix;
  char *suffix;
  char *star;
  grub_gfxmenu_box_t box;

  star = grub_strchr (abspattern, '*');
  if (! star)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
                       "missing `*' in box pixmap pattern `%s'", abspattern);

  /* Prefix:  Get the part before the '*'.  */
  prefix = grub_malloc (star - abspattern + 1);
  if (! prefix)
    return grub_errno;

  grub_memcpy (prefix, abspattern, star - abspattern);
  prefix[star - abspattern] = '\0';

  /* Suffix:  Everything after the '*' is the suffix.  */
  suffix = star + 1;

  box = grub_gfxmenu_create_box (prefix, suffix);
  grub_free (prefix);
  if (! box)
    return grub_errno;

  if (*boxptr)
    (*boxptr)->destroy (*boxptr);
  *boxptr = box;
  return grub_errno;
}
Esempio n. 7
0
grub_err_t
grub_rescue_parse_line (char *line,
			grub_reader_getline_t getline, void *getline_data)
{
  char *name;
  int n;
  grub_command_t cmd;
  char **args;

  if (grub_parser_split_cmdline (line, getline, getline_data, &n, &args)
      || n < 0)
    return grub_errno;

  if (n == 0)
    return GRUB_ERR_NONE;

  /* In case of an assignment set the environment accordingly
     instead of calling a function.  */
  if (n == 1)
    {
      char *val = grub_strchr (args[0], '=');

      if (val)
	{
	  val[0] = 0;
	  grub_env_set (args[0], val + 1);
	  val[0] = '=';
	  goto quit;
	}
    }

  /* Get the command name.  */
  name = args[0];

  /* If nothing is specified, restart.  */
  if (*name == '\0')
    goto quit;

  cmd = grub_command_find (name);
  if (cmd)
    {
      (cmd->func) (cmd, n - 1, &args[1]);
    }
  else
    {
      grub_printf_ (N_("Unknown command `%s'.\n"), name);
      if (grub_command_find ("help"))
	grub_printf ("Try `help' for usage\n");
    }

 quit:
  /* Arguments are returned in single memory chunk separated by zeroes */
  grub_free (args[0]);
  grub_free (args);

  return grub_errno;
}
Esempio n. 8
0
/* Get the device arguments of the Open Firmware node name `path'.  */
static char *
grub_ieee1275_get_devargs (const char *path)
{
  char *colon = grub_strchr (path, ':');

  if (! colon)
    return 0;

  return grub_strdup (colon + 1);
}
Esempio n. 9
0
grub_command_t
grub_command_find (char *cmdline)
{
  char *first_space;
  grub_command_t cmd;
  int count = 0;
  
  first_space = grub_strchr (cmdline, ' ');
  if (first_space)
    *first_space = '\0';

 again:
  
  for (cmd = grub_command_list; cmd; cmd = cmd->next)
    if (grub_strcmp (cmdline, cmd->name) == 0)
      break;

  if (! cmd)
    grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", cmdline);
  else if (cmd->flags & GRUB_COMMAND_FLAG_NOT_LOADED)
    {
      /* Automatically load the command.  */
      if (count == 0)
	{
	  grub_dl_t mod;
	  char *module_name;

	  module_name = grub_strdup (cmd->module_name);
	  if (module_name)
	    {
	      mod = grub_dl_load (module_name);
	      if (mod)
		{
		  grub_dl_ref (mod);
		  count++;
		  grub_free (module_name);
  		  goto again;
		}

	      grub_free (module_name);
	    }
	}

      /* This module seems broken.  */
      grub_unregister_command (cmdline);
      grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", cmdline);
      cmd = 0;
    }
  
  if (first_space)
    *first_space = ' ';

  return cmd;
}
Esempio n. 10
0
static void
grub_parse_cmdline (void)
{
  grub_ssize_t actual;
  char args[256];

  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
				  sizeof args, &actual) == 0
      && actual > 1)
    {
      int i = 0;

      while (i < actual)
	{
	  char *command = &args[i];
	  char *end;
	  char *val;

	  end = grub_strchr (command, ';');
	  if (end == 0)
	    i = actual; /* No more commands after this one.  */
	  else
	    {
	      *end = '\0';
	      i += end - command + 1;
	      while (grub_isspace(args[i]))
		i++;
	    }

	  /* Process command.  */
	  val = grub_strchr (command, '=');
	  if (val)
	    {
	      *val = '\0';
	      grub_env_set (command, val + 1);
	    }
	}
    }
}
Esempio n. 11
0
char *
grub_menu_next_field (char *name, char c)
{
  char *p;

  p = grub_strchr (name, c);
  if (p)
    {
      *(p++) = '\0';
    }

  return p;
}
Esempio n. 12
0
static grub_err_t
grub_cmd_next (grub_extcmd_context_t ctxt, int argc, char **args)
{
  struct grub_arg_list *state = ctxt->state;
  char *p, *root = NULL, *part_name = NULL, *part_guid = NULL;

  /* TODO: Add a uuid parser and a command line flag for providing type.  */
  grub_gpt_part_type_t part_type = GRUB_GPT_PARTITION_TYPE_USR_X86_64;

  if (!state[NEXT_SET_DEVICE].set || !state[NEXT_SET_UUID].set)
    {
      grub_error (GRUB_ERR_INVALID_COMMAND, N_("-d and -u are required"));
      goto done;
    }

  if (argc == 0)
    root = grub_strdup (grub_env_get ("root"));
  else if (argc == 1)
    root = grub_strdup (args[0]);
  else
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected arguments"));
      goto done;
    }

  if (!root)
    goto done;

  /* To make using $root practical strip off the partition name.  */
  p = grub_strchr (root, ',');
  if (p)
    *p = '\0';

  if (grub_find_next (root, &part_type, &part_name, &part_guid))
    goto done;

  if (grub_env_set (state[NEXT_SET_DEVICE].arg, part_name))
    goto done;

  if (grub_env_set (state[NEXT_SET_UUID].arg, part_guid))
    goto done;

  grub_errno = GRUB_ERR_NONE;

done:
  grub_free (root);
  grub_free (part_name);
  grub_free (part_guid);

  return grub_errno;
}
Esempio n. 13
0
grub_autolist_t
grub_autolist_load (const char *name)
{
  grub_autolist_t result = 0;
  const char *prefix;

  prefix = grub_env_get ("prefix");
  if (prefix)
    {
      char *filename;

      filename = grub_xasprintf ("%s/%s", prefix, name);
      if (filename)
	{
	  grub_file_t file;

	  file = grub_file_open (filename);
	  if (file)
	    {
	      char *buf = NULL;
	      for (;; grub_free (buf))
		{
		  char *p;

		  buf = grub_getline (file);

		  if (! buf)
		    break;

		  if (! grub_isgraph (buf[0]))
		    continue;

		  p = grub_strchr (buf, ':');
		  if (! p)
		    continue;

		  *p = '\0';
		  while (*++p == ' ')
		    ;

		  insert_item (&result, buf, p);
		}
	      grub_file_close (file);
	    }
	  grub_free (filename);
	}
    }

  return result;
}
Esempio n. 14
0
int
grub_parse_color_name_pair (grub_uint8_t *color, const char *name)
{
  int result = 1;
  grub_uint8_t fg, bg;
  char *fg_name, *bg_name;

  /* nothing specified by user */
  if (name == NULL)
    return result;

  fg_name = grub_strdup (name);
  if (fg_name == NULL)
    {
      /* "out of memory" message was printed by grub_strdup() */
      grub_wait_after_message ();
      return result;
    }

  bg_name = grub_strchr (fg_name, '/');
  if (bg_name == NULL)
    {
      grub_printf_ (N_("Warning: syntax error (missing slash) in `%s'\n"), fg_name);
      grub_wait_after_message ();
      goto free_and_return;
    }

  *(bg_name++) = '\0';

  if (parse_color_name (&fg, fg_name) == -1)
    {
      grub_printf_ (N_("Warning: invalid foreground color `%s'\n"), fg_name);
      grub_wait_after_message ();
      goto free_and_return;
    }
  if (parse_color_name (&bg, bg_name) == -1)
    {
      grub_printf_ (N_("Warning: invalid background color `%s'\n"), bg_name);
      grub_wait_after_message ();
      goto free_and_return;
    }

  *color = (bg << 4) | fg;
  result = 0;

free_and_return:
  grub_free (fg_name);
  return result;
}
Esempio n. 15
0
static grub_err_t
grub_gettext_init_ext (struct grub_gettext_context *ctx,
		       const char *locale,
		       const char *locale_dir, const char *prefix)
{
  const char *part1, *part2;
  grub_err_t err;

  grub_gettext_delete_list (ctx);

  if (!locale || locale[0] == 0)
    return 0;

  part1 = locale_dir;
  part2 = "";
  if (!part1 || part1[0] == 0)
    {
      part1 = prefix;
      part2 = "/locale";
    }

  if (!part1 || part1[0] == 0)
    return 0;

  err = grub_mofile_open_lang (ctx, part1, part2, locale);

  /* ll_CC didn't work, so try ll.  */
  if (err)
    {
      char *lang = grub_strdup (locale);
      char *underscore = lang ? grub_strchr (lang, '_') : 0;

      if (underscore)
	{
	  *underscore = '\0';
	  grub_errno = GRUB_ERR_NONE;
	  err = grub_mofile_open_lang (ctx, part1, part2, lang);
	}

      grub_free (lang);
    }

  if (locale[0] == 'e' && locale[1] == 'n'
      && (locale[2] == '\0' || locale[2] == '_'))
    grub_errno = err = GRUB_ERR_NONE;
  return err;
}
Esempio n. 16
0
char *
grub_util_get_devmapper_grub_dev (const char *os_dev)
{
  char *uuid, *optr;
  char *grub_dev;

  uuid = get_dm_uuid (os_dev);
  if (!uuid)
    return NULL;
  
  if (strncmp (uuid, "LVM-", sizeof ("LVM-") - 1) == 0)
    {
	unsigned i;
	int dashes[] = { 0, 6, 10, 14, 18, 22, 26, 32, 38, 42, 46, 50, 54, 58};
	grub_dev = xmalloc (grub_strlen (uuid) + 40);
	optr = grub_stpcpy (grub_dev, "lvmid/");
	for (i = 0; i < ARRAY_SIZE (dashes) - 1; i++)
	  {
	    memcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i],
		    dashes[i+1] - dashes[i]);
	    optr += dashes[i+1] - dashes[i];
	    *optr++ = '-';
	  }
	optr = stpcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i]);
	*optr = '\0';
	grub_dev[sizeof("lvmid/xxxxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxxxx") - 1]
	  = '/';
	free (uuid);
	return grub_dev;
      }

  if (strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0)
    {
      char *dash;
      dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-');
      if (dash)
	*dash = 0;
      grub_dev = grub_xasprintf ("cryptouuid/%s",
				 uuid + sizeof ("CRYPT-LUKS1-") - 1);
      grub_free (uuid);
      return grub_dev;
    }
  grub_free (uuid);
  return NULL;
}
Esempio n. 17
0
void
grub_machine_set_prefix (void)
{
  if (grub_prefix[0] != '(')
    {
      char bootpath[IEEE1275_MAX_PATH_LEN];
      char *prefix, *path, *colon;
      grub_ssize_t actual;

      if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath",
				      &bootpath, sizeof (bootpath), &actual))
	{
	  /* Should never happen.  */
	  grub_printf ("/chosen/bootpath property missing!\n");
	  grub_env_set ("prefix", "");
	  return;
	}

      /* Transform an OF device path to a GRUB path.  */
      colon = grub_strchr (bootpath, ':');
      if (colon)
	{
	  char *part = colon + 1;

	  /* Consistently provide numbered partitions to GRUB.
	     OpenBOOT traditionally uses alphabetical partition
	     specifiers.  */
	  if (part[0] >= 'a' && part[0] <= 'z')
	    part[0] = '1' + (part[0] - 'a');
	}
      prefix = grub_ieee1275_encode_devname (bootpath);

      path = grub_xasprintf("%s%s", prefix, grub_prefix);

      grub_strcpy (grub_prefix, path);

      grub_free (path);
      grub_free (prefix);
    }

  grub_env_set ("prefix", grub_prefix);
}
Esempio n. 18
0
/* Get the device path of the Open Firmware node name `path'.  */
static char *
grub_ieee1275_get_devname (const char *path)
{
  char *colon = grub_strchr (path, ':');
  struct grub_ieee1275_get_devname_closure c;

  c.path = path;
  c.newpath = 0;
  c.pathlen = grub_strlen (path);

  if (colon)
    c.pathlen = (int)(colon - path);

  /* Try to find an alias for this device.  */
  grub_devalias_iterate (match_alias, &c);

  if (! c.newpath)
    c.newpath = grub_strndup (path, c.pathlen);

  return c.newpath;
}
Esempio n. 19
0
/* Helper for grub_parser_execute.  */
static grub_err_t
grub_parser_execute_getline (char **line, int cont __attribute__ ((unused)),
			     void *data)
{
  char **source = data;
  char *p;

  if (!*source)
    {
      *line = 0;
      return 0;
    }

  p = grub_strchr (*source, '\n');

  if (p)
    *line = grub_strndup (*source, p - *source);
  else
    *line = grub_strdup (*source);
  *source = p ? p + 1 : 0;
  return 0;
}
Esempio n. 20
0
/* Load all loadable kexts placed under DIRNAME and matching OSBUNDLEREQUIRED */
grub_err_t
grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
			     int maxrecursion)
{
  grub_device_t dev;
  char *device_name;
  grub_fs_t fs;
  const char *path;

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");

  device_name = grub_file_get_device_name (dirname);
  dev = grub_device_open (device_name);
  if (dev)
    {
      struct grub_xnu_scan_dir_for_kexts_closure c;

      fs = grub_fs_probe (dev);
      path = grub_strchr (dirname, ')');
      if (! path)
	path = dirname;
      else
	path++;

      c.dirname = dirname;
      c.osbundlerequired = osbundlerequired;
      c.maxrecursion = maxrecursion;
      if (fs)
	(fs->dir) (dev, path, grub_xnu_scan_dir_for_kexts_hook, 0);
      grub_device_close (dev);
    }
  grub_free (device_name);

  return GRUB_ERR_NONE;
}
Esempio n. 21
0
/* Print the information on the device NAME.  */
grub_err_t
grub_normal_print_device_info (const char *name)
{
    grub_device_t dev;
    char *p;

    p = grub_strchr (name, ',');
    if (p)
    {
        grub_xputs ("\t");
        grub_printf_ (N_("Partition %s:"), name);
        grub_xputs (" ");
    }
    else
    {
        grub_printf_ (N_("Device %s:"), name);
        grub_xputs (" ");
    }

    dev = grub_device_open (name);
    if (! dev)
        grub_printf ("%s", _("Filesystem cannot be accessed"));
    else if (dev->disk)
    {
        grub_fs_t fs;

        fs = grub_fs_probe (dev);
        /* Ignore all errors.  */
        grub_errno = 0;

        if (fs)
        {
            grub_printf_ (N_("Filesystem type %s"), fs->name);
            if (fs->label)
            {
                char *label;
                (fs->label) (dev, &label);
                if (grub_errno == GRUB_ERR_NONE)
                {
                    if (label && grub_strlen (label))
                    {
                        grub_xputs (" ");
                        grub_printf_ (N_("- Label \"%s\""), label);
                    }
                    grub_free (label);
                }
                grub_errno = GRUB_ERR_NONE;
            }
            if (fs->mtime)
            {
                grub_int32_t tm;
                struct grub_datetime datetime;
                (fs->mtime) (dev, &tm);
                if (grub_errno == GRUB_ERR_NONE)
                {
                    grub_unixtime2datetime (tm, &datetime);
                    grub_xputs (" ");
                    grub_printf_ (N_("- Last modification time %d-%02d-%02d "
                                     "%02d:%02d:%02d %s"),
                                  datetime.year, datetime.month, datetime.day,
                                  datetime.hour, datetime.minute, datetime.second,
                                  grub_get_weekday_name (&datetime));

                }
                grub_errno = GRUB_ERR_NONE;
            }
            if (fs->uuid)
            {
                char *uuid;
                (fs->uuid) (dev, &uuid);
                if (grub_errno == GRUB_ERR_NONE)
                {
                    if (uuid && grub_strlen (uuid))
                        grub_printf (", UUID %s", uuid);
                    grub_free (uuid);
                }
                grub_errno = GRUB_ERR_NONE;
            }
        }
        else if (! dev->disk->has_partitions || dev->disk->partition)
            grub_printf ("%s", _("Unknown filesystem"));
        else
            grub_printf ("%s", _("Partition table"));

        grub_device_close (dev);
    }

    grub_xputs ("\n");
    return grub_errno;
}
Esempio n. 22
0
/* Parse a test expression starting from *argn. */
static int
test_parse (char **args, int *argn, int argc)
{
  int ret = 0, discard = 0, invert = 0;
  int file_exists;
  struct grub_dirhook_info file_info;

  auto void update_val (int val);
  auto void get_fileinfo (char *pathname);

  /* Take care of discarding and inverting. */
  void update_val (int val)
  {
    if (! discard)
      ret = invert ? ! val : val;
    invert = discard = 0;
  }

  /* Check if file exists and fetch its information. */
  void get_fileinfo (char *path)
  {
    char *filename, *pathname;
    char *device_name;
    grub_fs_t fs;
    grub_device_t dev;

    /* A hook for iterating directories. */
    auto int find_file (const char *cur_filename,
			const struct grub_dirhook_info *info);
    int find_file (const char *cur_filename,
		   const struct grub_dirhook_info *info)
    {
      if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename)
	   : grub_strcmp (cur_filename, filename)) == 0)
	{
	  file_info = *info;
	  file_exists = 1;
	  return 1;
	}
      return 0;
    }

    file_exists = 0;
    device_name = grub_file_get_device_name (path);
    dev = grub_device_open (device_name);
    if (! dev)
      {
	grub_free (device_name);
	return;
      }

    fs = grub_fs_probe (dev);
    if (! fs)
      {
	grub_free (device_name);
	grub_device_close (dev);
	return;
      }

    pathname = grub_strchr (path, ')');
    if (! pathname)
      pathname = path;
    else
      pathname++;

    /* Remove trailing '/'. */
    while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
      pathname[grub_strlen (pathname) - 1] = 0;

    /* Split into path and filename. */
    filename = grub_strrchr (pathname, '/');
    if (! filename)
      {
	path = grub_strdup ("/");
	filename = pathname;
      }
    else
      {
	filename++;
	path = grub_strdup (pathname);
	path[filename - pathname] = 0;
      }

    /* It's the whole device. */
    if (! *pathname)
      {
	file_exists = 1;
	grub_memset (&file_info, 0, sizeof (file_info));
	/* Root is always a directory. */
	file_info.dir = 1;

	/* Fetch writing time. */
	file_info.mtimeset = 0;
	if (fs->mtime)
	  {
	    if (! fs->mtime (dev, &file_info.mtime))
	      file_info.mtimeset = 1;
	    grub_errno = GRUB_ERR_NONE;
	  }
      }
    else
      (fs->dir) (dev, path, find_file);

    grub_device_close (dev);
    grub_free (path);
    grub_free (device_name);
  }
Esempio n. 23
0
static grub_err_t
grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
		     int argc, char **args_in)
{
  char *uuid_root = 0, *uuid_prefix, *prefdev = 0;
  const char *prefix = 0;
  const char *path_prefix = 0;
  int mods_loaded = 0;
  grub_dl_t *mods;
  const char **args;
  int i;

  if (argc == 0)
    {
      argc = ARRAY_SIZE (modnames_def);
      args = modnames_def;
    }
  else
    args = (const char **) args_in;

  prefix = grub_env_get ("prefix");

  if (! prefix)
    return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");

  if (prefix)
    path_prefix = (prefix[0] == '(') ? grub_strchr (prefix, ')') : NULL;
  if (path_prefix)
    path_prefix++;
  else
    path_prefix = prefix;

  mods = grub_malloc (argc * sizeof (mods[0]));
  if (!mods)
    return grub_errno;

  if (get_uuid (NULL, &uuid_root, 0))
    return grub_errno;

  prefdev = grub_file_get_device_name (prefix);
  if (grub_errno)
    {
      grub_print_error ();
      prefdev = 0;
    }

  if (get_uuid (prefdev, &uuid_prefix, 0))
    {
      grub_free (uuid_root);
      return grub_errno;
    }

  grub_dprintf ("nativedisk", "uuid_prefix = %s, uuid_root = %s\n",
		uuid_prefix, uuid_root);

  for (mods_loaded = 0; mods_loaded < argc; mods_loaded++)
    {
      char *filename;
      grub_dl_t mod;
      grub_file_t file = NULL;
      grub_ssize_t size;
      void *core = 0;

      mod = grub_dl_get (args[mods_loaded]);
      if (mod)
	{
	  mods[mods_loaded] = 0;
	  continue;
	}

      filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod",
				 prefix, args[mods_loaded]);
      if (! filename)
	goto fail;

      file = grub_file_open (filename);
      grub_free (filename);
      if (! file)
	goto fail;

      size = grub_file_size (file);
      core = grub_malloc (size);
      if (! core)
	{
	  grub_file_close (file);
	  goto fail;
	}

      if (grub_file_read (file, core, size) != (grub_ssize_t) size)
	{
	  grub_file_close (file);
	  grub_free (core);
	  goto fail;
	}

      grub_file_close (file);

      mods[mods_loaded] = grub_dl_load_core_noinit (core, size);
      if (! mods[mods_loaded])
	goto fail;
    }

  for (i = 0; i < argc; i++)
    if (mods[i])
      grub_dl_init (mods[i]);

  if (uuid_prefix || uuid_root)
    {
      struct search_ctx ctx;
      grub_fs_autoload_hook_t saved_autoload;

      /* No need to autoload FS since obviously we already have the necessary fs modules.  */
      saved_autoload = grub_fs_autoload_hook;
      grub_fs_autoload_hook = 0;

      ctx.root_uuid = uuid_root;
      ctx.prefix_uuid = uuid_prefix;
      ctx.prefix_path = path_prefix;
      ctx.prefix_found = !uuid_prefix;
      ctx.root_found = !uuid_root;

      /* FIXME: try to guess the correct values.  */
      grub_device_iterate (iterate_device, &ctx);

      grub_fs_autoload_hook = saved_autoload;
    }
  grub_free (uuid_root);
  grub_free (uuid_prefix);

  return GRUB_ERR_NONE;

 fail:
  grub_free (uuid_root);
  grub_free (uuid_prefix);

  for (i = 0; i < mods_loaded; i++)
    if (mods[i])
      {
	mods[i]->fini = 0;
	grub_dl_unload (mods[i]);
      }
  return grub_errno;
}
Esempio n. 24
0
/* Read the file crypto.lst for auto-loading.  */
void
read_crypto_list (const char *prefix)
{
  char *filename;
  grub_file_t file;
  char *buf = NULL;

  if (!prefix)
    {
      grub_errno = GRUB_ERR_NONE;
      return;
    }
  
  filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM
			     "/crypto.lst", prefix);
  if (!filename)
    {
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  file = grub_file_open (filename);
  grub_free (filename);
  if (!file)
    {
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  /* Override previous crypto.lst.  */
  grub_crypto_spec_free ();

  for (;; grub_free (buf))
    {
      char *p, *name;
      struct load_spec *cur;
      
      buf = grub_file_getline (file);
	
      if (! buf)
	break;
      
      name = buf;
      while (grub_isspace (name[0]))
	name++;

      p = grub_strchr (name, ':');
      if (! p)
	continue;
      
      *p = '\0';
      p++;
      while (*p == ' ' || *p == '\t')
	p++;

      cur = grub_malloc (sizeof (*cur));
      if (!cur)
	{
	  grub_errno = GRUB_ERR_NONE;
	  continue;
	}
      
      cur->name = grub_strdup (name);
      if (! name)
	{
	  grub_errno = GRUB_ERR_NONE;
	  grub_free (cur);
	  continue;
	}
	
      cur->modname = grub_strdup (p);
      if (! cur->modname)
	{
	  grub_errno = GRUB_ERR_NONE;
	  grub_free (cur);
	  grub_free (cur->name);
	  continue;
	}
      cur->next = crypto_specs;
      crypto_specs = cur;
    }
  
  grub_file_close (file);

  grub_errno = GRUB_ERR_NONE;

  grub_crypto_autoload_hook = grub_crypto_autoload;
}
Esempio n. 25
0
static char *
grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
{
  char type[64]; /* XXX check size.  */
  char *device = grub_ieee1275_get_devname (path);
  char *args = grub_ieee1275_get_devargs (path);
  char *ret = 0;
  grub_ieee1275_phandle_t dev;

  if (!args)
    /* Shouldn't happen.  */
    return 0;

  /* We need to know what type of device it is in order to parse the full
     file path properly.  */
  if (grub_ieee1275_finddevice (device, &dev))
    {
      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Device %s not found\n", device);
      goto fail;
    }
  if (grub_ieee1275_get_property (dev, "device_type", &type, sizeof type, 0))
    {
      grub_error (GRUB_ERR_UNKNOWN_DEVICE,
		  "Device %s lacks a device_type property\n", device);
      goto fail;
    }

  if (!grub_strcmp ("block", type))
    {
      /* The syntax of the device arguments is defined in the CHRP and PReP
         IEEE1275 bindings: "[partition][,[filename]]".  */
      char *comma = grub_strchr (args, ',');

      if (ptype == GRUB_PARSE_FILENAME)
	{
	  if (comma)
	    {
	      char *filepath = comma + 1;

	      ret = grub_malloc (grub_strlen (filepath) + 1);
	      /* Make sure filepath has leading backslash.  */
	      if (filepath[0] != '\\')
		grub_sprintf (ret, "\\%s", filepath);
	      else
		grub_strcpy (ret, filepath);
	    }
	}
      else if (ptype == GRUB_PARSE_PARTITION)
        {
	  if (!comma)
	    ret = grub_strdup (args);
	  else
	    ret = grub_strndup (args, (grub_size_t)(comma - args));
	}
    }
  else
    {
      /* XXX Handle net devices by configuring & registering a grub_net_dev
	 here, then return its name?
	 Example path: "net:<server ip>,<file name>,<client ip>,<gateway
	 ip>,<bootp retries>,<tftp retries>".  */
      grub_printf ("Unsupported type %s for device %s\n", type, device);
    }

fail:
  grub_free (device);
  grub_free (args);
  return ret;
}
Esempio n. 26
0
File: ls.c Progetto: hisilicon/grub
static grub_err_t
grub_ls_list_files (char *dirname, int longlist, int all, int human)
{
  char *device_name;
  grub_fs_t fs;
  const char *path;
  grub_device_t dev;

  device_name = grub_file_get_device_name (dirname);
  dev = grub_device_open (device_name);
  if (! dev)
    goto fail;

  fs = grub_fs_probe (dev);
  path = grub_strchr (dirname, ')');
  if (! path)
    path = dirname;
  else
    path++;

  if (! path && ! device_name)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
      goto fail;
    }

  if (! *path)
    {
      if (grub_errno == GRUB_ERR_UNKNOWN_FS)
	grub_errno = GRUB_ERR_NONE;

      grub_normal_print_device_info (device_name);
    }
  else if (fs)
    {
      struct grub_ls_list_files_ctx ctx = {
	.dirname = dirname,
	.all = all,
	.human = human
      };

      if (longlist)
	(fs->dir) (dev, path, print_files_long, &ctx);
      else
	(fs->dir) (dev, path, print_files, &ctx);

      if (grub_errno == GRUB_ERR_BAD_FILE_TYPE
	  && path[grub_strlen (path) - 1] != '/')
	{
	  /* PATH might be a regular file.  */
	  char *p;
	  grub_file_t file;
	  struct grub_dirhook_info info;
	  grub_errno = 0;

	  grub_file_filter_disable_compression ();
	  file = grub_file_open (dirname);
	  if (! file)
	    goto fail;

	  grub_file_close (file);

	  p = grub_strrchr (dirname, '/') + 1;
	  dirname = grub_strndup (dirname, p - dirname);
	  if (! dirname)
	    goto fail;

	  all = 1;
	  grub_memset (&info, 0, sizeof (info));
	  if (longlist)
	    print_files_long (p, &info, &ctx);
	  else
	    print_files (p, &info, &ctx);

	  grub_free (dirname);
	}

      if (grub_errno == GRUB_ERR_NONE)
	grub_xputs ("\n");

      grub_refresh ();
    }

 fail:
  if (dev)
    grub_device_close (dev);

  grub_free (device_name);

  return 0;
}
Esempio n. 27
0
char *
grub_legacy_parse (const char *buf, char **entryname, char **suffix)
{
  const char *ptr;
  const char *cmdname;
  unsigned i, cmdnum;
  char *args[ARRAY_SIZE (legacy_commands[0].argt)];

  *suffix = NULL;

  for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
  if (!*ptr || *ptr == '#')
    {
      char *ret;
      int len = grub_strlen (buf);
      ret = grub_malloc (len + 2);
      grub_memcpy (ret, buf, len);
      if (len && ret[len - 1] == '\n')
	ret[len] = 0;
      else
	{
	  ret[len] = '\n';
	  ret[len + 1] = 0;
	}
      return ret;
    }

  cmdname = ptr;
  for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++);

  for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++)
    if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0
	&& legacy_commands[cmdnum].name[ptr - cmdname] == 0
	&& (!(*entryname != NULL && (legacy_commands[cmdnum].flags
				     & FLAG_NO_MENUENTRY)))
	&& (!(*entryname == NULL && (legacy_commands[cmdnum].flags
				     & FLAG_MENUENTRY_ONLY))))
      break;
  if (cmdnum == ARRAY_SIZE (legacy_commands))
    return grub_xasprintf ("# Unsupported legacy command: %s\n", buf);

  for (; grub_isspace (*ptr) || *ptr == '='; ptr++);

  if (legacy_commands[cmdnum].flags & FLAG_TITLE)
    {
      const char *ptr2;
      ptr2 = ptr + grub_strlen (ptr);
      while (ptr2 > ptr && grub_isspace (*(ptr2 - 1)))
	ptr2--;
      *entryname = grub_strndup (ptr, ptr2 - ptr);
      return NULL;
    }

  if (legacy_commands[cmdnum].flags & FLAG_TERMINAL)
    {
      int dumb = 0, lines = 24;
#ifdef TODO
      int no_echo = 0, no_edit = 0;
#endif
      int hercules = 0;
      int console = 0, serial = 0, graphics = 0;
      /* Big enough for any possible resulting command. */
      char outbuf[512] = "";
      char *outptr;
      while (*ptr)
	{
	  /*	  "[--timeout=SECS] [--silent]"
		  " [console] [serial] [hercules]"*/
	  if (grub_memcmp (ptr, "--dumb", sizeof ("--dumb") - 1) == 0)
	    dumb = 1;
#ifdef TODO
	  if (grub_memcmp (ptr, "--no-echo", sizeof ("--no-echo") - 1) == 0)
	    no_echo = 1;

	  if (grub_memcmp (ptr, "--no-edit", sizeof ("--no-edit") - 1) == 0)
	    no_edit = 1;
#endif
	  if (grub_memcmp (ptr, "--lines=", sizeof ("--lines=") - 1) == 0)
	    {
	      lines = grub_strtoul (ptr + sizeof ("--lines=") - 1, 0, 0);
	      if (grub_errno)
		{
		  lines = 24;
		  grub_errno = GRUB_ERR_NONE;
		}
	    }

	  if (grub_memcmp (ptr, "console", sizeof ("console") - 1) == 0)
	    console = 1;

	  if (grub_memcmp (ptr, "serial", sizeof ("serial") - 1) == 0)
	    serial = 1;
	  if (grub_memcmp (ptr, "hercules", sizeof ("hercules") - 1) == 0)
	    hercules = 1;
	  if (grub_memcmp (ptr, "graphics", sizeof ("graphics") - 1) == 0)
	    graphics = 1;
	  while (*ptr && !grub_isspace (*ptr))
	    ptr++;
	  while (*ptr && grub_isspace (*ptr))
	    ptr++;
	}

      if (!console && !serial && !hercules && !graphics)
	return grub_strdup ("terminal_input; terminal_output; terminfo\n");

      outptr = outbuf;

      if (graphics)
	outptr = grub_stpcpy (outptr, "insmod all_video; ");

      outptr = grub_stpcpy (outptr, "terminal_input ");
      if (serial)
	outptr = grub_stpcpy (outptr, "serial ");
      if (console || hercules || graphics)
	outptr = grub_stpcpy (outptr, "console ");
      outptr = grub_stpcpy (outptr, "; terminal_output ");
      if (serial)
	outptr = grub_stpcpy (outptr, "serial ");
      if (console)
	outptr = grub_stpcpy (outptr, "console ");
      if (hercules)
	outptr = grub_stpcpy (outptr, "mda_text ");
      if (graphics)
	outptr = grub_stpcpy (outptr, "gfxterm ");
      outptr = grub_stpcpy (outptr, "; ");
      *outptr = '\0';
      if (serial)
	{
	  grub_snprintf (outptr, outbuf + sizeof (outbuf) - outptr,
			 "terminfo serial -g 80x%d %s; ",
			 lines, dumb ? "dumb" : "vt100");
	  outptr += grub_strlen (outptr);
	}

      grub_strcpy (outptr, "\n");

      return grub_strdup (outbuf);
    }

  grub_memset (args, 0, sizeof (args));

  {
    int hold_arg = 0;
    const char *curarg = NULL; 
    for (i = 0; i < legacy_commands[cmdnum].argc; i++)
      {
 	grub_size_t curarglen;
	if (hold_arg)
	  {
	    ptr = curarg;
	    hold_arg = 0;
	  }
	for (; grub_isspace (*ptr); ptr++);
	curarg = ptr;
	if (!*curarg)
	  break;
	for (; *ptr && !grub_isspace (*ptr); ptr++);
	if (i != legacy_commands[cmdnum].argc - 1
	    || (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST))
	  curarglen = ptr - curarg;
	else
	  {
	    curarglen = grub_strlen (curarg);
	    while (curarglen > 0 && grub_isspace (curarg[curarglen - 1]))
	      curarglen--;
	  }
	if (*ptr)
	  ptr++;
	switch (legacy_commands[cmdnum].argt[i])
	  {
	  case TYPE_FILE_NO_CONSUME:
	    hold_arg = 1;
	  case TYPE_PARTITION:
	  case TYPE_FILE:
	    args[i] = adjust_file (curarg, curarglen);
	    break;

	  case TYPE_REST_VERBATIM:
	    {
	      char *outptr, *outptr0;
	      int overhead = 3;
	      ptr = curarg;
	      while (*ptr)
		{
		  for (; *ptr && grub_isspace (*ptr); ptr++);
		  for (; *ptr && !grub_isspace (*ptr); ptr++)
		    if (*ptr == '\'')
		      overhead += 3;
		  if (*ptr)
		    ptr++;
		  overhead += 3;
		}
		
	      outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg));
	      if (!outptr0)
		return NULL;
	      ptr = curarg;
	      outptr = outptr0;
	      while (*ptr)
		{
		  for (; *ptr && grub_isspace (*ptr); ptr++);
		  if (outptr != outptr0)
		    *outptr++ = ' ';
		  *outptr++ = '\'';
		  for (; *ptr && !grub_isspace (*ptr); ptr++)
		    {
		      if (*ptr == '\'')
			{
			  *outptr++ = '\'';
			  *outptr++ = '\\';
			  *outptr++ = '\'';
			  *outptr++ = '\'';
			}
		      else
			*outptr++ = *ptr;
		    }
		  *outptr++ = '\'';
		  if (*ptr)
		    ptr++;
		}
	      *outptr++ = 0;
	    }
	    break;

	  case TYPE_VERBATIM:
	    args[i] = grub_legacy_escape (curarg, curarglen);
	    break;
	  case TYPE_WITH_CONFIGFILE_OPTION:
	  case TYPE_FORCE_OPTION:
	  case TYPE_NOAPM_OPTION:
	  case TYPE_TYPE_OR_NOMEM_OPTION:
	  case TYPE_OPTION:
	    if (is_option (legacy_commands[cmdnum].argt[i], curarg, curarglen))
	      {
		args[i] = grub_strndup (curarg, curarglen);
		break;
	      }
	    args[i] = grub_strdup ("");
	    hold_arg = 1;
	    break;
	  case TYPE_INT:
	    {
	      const char *brk;
	      int base = 10;
	      brk = curarg;
	      if (brk[0] == '0' && brk[1] == 'x')
		{
		  base = 16;
		  brk += 2;
		}
	      else if (brk[0] == '0')
		base = 8;
	      for (; *brk && brk < curarg + curarglen; brk++)
		{
		  if (base == 8 &&  (*brk == '8' || *brk == '9'))
		    break;
		  if (grub_isdigit (*brk))
		    continue;
		  if (base != 16)
		    break;
		  if (!(*brk >= 'a' && *brk <= 'f')
		      && !(*brk >= 'A' && *brk <= 'F'))
		    break;
		}
	      if (brk == curarg)
		args[i] = grub_strdup ("0");
	      else
		args[i] = grub_strndup (curarg, brk - curarg);
	    }
	    break;
	  case TYPE_VBE_MODE:
	    {
	      unsigned mod;
	      struct grub_vesa_mode_table_entry *modedesc;

	      mod = grub_strtoul (curarg, 0, 0);
	      if (grub_errno)
		{
		  mod = 0;
		  grub_errno = GRUB_ERR_NONE;
		}
	      if (mod < GRUB_VESA_MODE_TABLE_START
		  || mod > GRUB_VESA_MODE_TABLE_END)
		{
		  args[i] = grub_strdup ("auto");
		  break;
		}
	      modedesc = &grub_vesa_mode_table[mod - GRUB_VESA_MODE_TABLE_START];
	      if (!modedesc->width)
		{
		  args[i] = grub_strdup ("auto");
		  break;
		}
	      args[i] = grub_xasprintf ("%ux%ux%u",
					modedesc->width, modedesc->height,
					modedesc->depth);
	      break;
	    }
	  case TYPE_BOOL:
	    if (curarglen == 2 && curarg[0] == 'o' && curarg[1] == 'n')
	      args[i] = grub_strdup ("1");
	    else
	      args[i] = grub_strdup ("0");
	    break;
	  }
      }
  }

  while (legacy_commands[cmdnum].argc > 0
	 && args[legacy_commands[cmdnum].argc - 1] == NULL
	 && (legacy_commands[cmdnum].flags & FLAG_FALLBACK_AVAILABLE)
	 && args[legacy_commands[cmdnum + 1].argc] == NULL)
    cmdnum++;

  for (; i < legacy_commands[cmdnum].argc; i++)
    switch (legacy_commands[cmdnum].argt[i])
      {
      case TYPE_FILE_NO_CONSUME:
      case TYPE_PARTITION:
      case TYPE_FILE:
      case TYPE_REST_VERBATIM:
      case TYPE_VERBATIM:
      case TYPE_WITH_CONFIGFILE_OPTION:
      case TYPE_FORCE_OPTION:
      case TYPE_NOAPM_OPTION:
      case TYPE_TYPE_OR_NOMEM_OPTION:
      case TYPE_OPTION:	
	args[i] = grub_strdup ("");
	break;
      case TYPE_BOOL:
      case TYPE_INT:
	args[i] = grub_strdup ("0");
	break;
      case TYPE_VBE_MODE:    
	args[i] = grub_strdup ("auto");
	break;
      }

  if (legacy_commands[cmdnum].flags & FLAG_COLOR_INVERT)
    {
      char *corig = args[legacy_commands[cmdnum].argc - 1];
      char *slash = grub_strchr (corig, '/');
      char *invert;
      grub_size_t len;

      len = grub_strlen (corig);
      if (!slash)
	{
	  grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid color specification `%s'"),
		      args[0]);
	  return NULL;
	}
      invert = grub_malloc (len + 1);
      if (!invert)
	return NULL;
      grub_memcpy (invert, slash + 1, len - (slash - corig) - 1);
      invert[len - (slash - args[0]) - 1] = '/'; 
      grub_memcpy (invert + len - (slash - corig), corig, slash - corig);
      invert[len] = 0;
      args[legacy_commands[cmdnum].argc] = invert;
    }

  if (legacy_commands[cmdnum].suffix)
    {
      *suffix = grub_xasprintf (legacy_commands[cmdnum].suffix,
				args[legacy_commands[cmdnum].suffixarg]);
      if (*suffix)
	return NULL;
    }

  {
    char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1],
				args[2], args[3]);
    grub_free (args[0]);
    grub_free (args[1]);
    grub_free (args[2]);
    grub_free (args[3]);
    return ret;
  }
}
Esempio n. 28
0
/* Load extension DIRNAME. (extensions are directories in xnu) */
grub_err_t
grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
			     int maxrecursion)
{
  grub_device_t dev;
  char *newdirname;
  char *newpath;
  char *device_name;
  grub_fs_t fs;
  const char *path;
  char *binsuffix;
  grub_file_t binfile;

  newdirname = grub_malloc (grub_strlen (dirname) + 20);
  if (! newdirname)
    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate buffer");
  grub_strcpy (newdirname, dirname);
  newdirname[grub_strlen (dirname)] = '/';
  newdirname[grub_strlen (dirname) + 1] = 0;
  device_name = grub_file_get_device_name (dirname);
  dev = grub_device_open (device_name);
  if (dev)
    {
      struct grub_xnu_load_kext_from_dir_closure c;

      fs = grub_fs_probe (dev);
      path = grub_strchr (dirname, ')');
      if (! path)
	path = dirname;
      else
	path++;

      newpath = grub_strchr (newdirname, ')');
      if (! newpath)
	newpath = newdirname;
      else
	newpath++;

      c.dirname = dirname;
      c.osbundlerequired = osbundlerequired;
      c.maxrecursion = maxrecursion;
      c.usemacos = 0;
      c.plistname = 0;
      c.newdirname = newdirname;
      /* Look at the directory. */
      if (fs)
	(fs->dir) (dev, path, grub_xnu_load_kext_from_dir_hook, &c);

      if (c.plistname && grub_xnu_check_os_bundle_required
	  (c.plistname, osbundlerequired, &binsuffix))
	{
	  if (binsuffix)
	    {
	      /* Open the binary. */
	      char *binname = grub_malloc (grub_strlen (dirname)
					   + grub_strlen (binsuffix)
					   + sizeof ("/MacOS/"));
	      grub_strcpy (binname, dirname);
	      if (c.usemacos)
		grub_strcpy (binname + grub_strlen (binname), "/MacOS/");
	      else
		grub_strcpy (binname + grub_strlen (binname), "/");
	      grub_strcpy (binname + grub_strlen (binname), binsuffix);
	      grub_dprintf ("xnu", "%s:%s\n", c.plistname, binname);
	      binfile = grub_gzfile_open (binname, 1);
	      if (! binfile)
		grub_errno = GRUB_ERR_NONE;

	      /* Load the extension. */
	      grub_xnu_load_driver (c.plistname, binfile);
	      grub_free (binname);
	      grub_free (binsuffix);
	    }
	  else
	    {
	      grub_dprintf ("xnu", "%s:0\n", c.plistname);
	      grub_xnu_load_driver (c.plistname, 0);
	    }
	}
      grub_free (c.plistname);
      grub_device_close (dev);
    }
  grub_free (device_name);

  return GRUB_ERR_NONE;
}
Esempio n. 29
0
static grub_err_t
grub_cpio_dir (grub_device_t device, const char *path,
	       int (*hook) (const char *filename,
			    const struct grub_dirhook_info *info))
{
  struct grub_cpio_data *data;
  grub_uint32_t ofs;
  char *prev, *name;
  const char *np;
  int len;

  grub_dl_ref (my_mod);

  prev = 0;

  data = grub_cpio_mount (device->disk);
  if (!data)
    goto fail;

  np = path + 1;
  len = grub_strlen (path) - 1;

  data->hofs = 0;
  while (1)
    {
      if (grub_cpio_find_file (data, &name, &ofs))
	goto fail;

      if (!ofs)
	break;

      if (grub_memcmp (np, name, len) == 0)
	{
	  char *p, *n;

	  n = name + len;
	  if (*n == '/')
	    n++;

	  p = grub_strchr (name + len, '/');
	  if (p)
	    *p = 0;

	  if ((!prev) || (grub_strcmp (prev, name) != 0))
	    {
	      struct grub_dirhook_info info;
	      grub_memset (&info, 0, sizeof (info));
	      info.dir = (p != NULL);

	      hook (name + len, &info);
	      if (prev)
		grub_free (prev);
	      prev = name;
	    }
	  else
	    grub_free (name);
	}
      data->hofs = ofs;
    }

fail:

  if (prev)
    grub_free (prev);

  if (data)
    grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Esempio n. 30
0
/* Load .kext. */
static grub_err_t
grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
{
  grub_macho_t macho;
  grub_err_t err;
  grub_file_t infoplist;
  struct grub_xnu_extheader *exthead;
  int neededspace = sizeof (*exthead);
  grub_uint8_t *buf;
  grub_size_t infoplistsize = 0, machosize = 0;
  char *name, *nameend;
  int namelen;

  name = get_name_ptr (infoplistname);
  nameend = grub_strchr (name, '/');

  if (nameend)
    namelen = nameend - name;
  else
    namelen = grub_strlen (name);

  neededspace += namelen + 1;

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");

  /* Compute the needed space. */
  if (binaryfile)
    {
      macho = grub_macho_file (binaryfile);
      if (! macho || ! grub_macho_contains_macho32 (macho))
	{
	  if (macho)
	    grub_macho_close (macho);
	  return grub_error (GRUB_ERR_BAD_OS,
			     "extension doesn't contain suitable architecture");
	}
      if (grub_xnu_is_64bit)
	machosize = grub_macho_filesize64 (macho);
      else
	machosize = grub_macho_filesize32 (macho);
      neededspace += machosize;
    }
  else
    macho = 0;

  if (infoplistname)
    infoplist = grub_gzfile_open (infoplistname, 1);
  else
    infoplist = 0;
  grub_errno = GRUB_ERR_NONE;
  if (infoplist)
    {
      infoplistsize = grub_file_size (infoplist);
      neededspace += infoplistsize + 1;
    }
  else
    infoplistsize = 0;

  /* Allocate the space. */
  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
  if (err)
    return err;
  buf = grub_xnu_heap_malloc (neededspace);

  exthead = (struct grub_xnu_extheader *) buf;
  grub_memset (exthead, 0, sizeof (*exthead));
  buf += sizeof (*exthead);

  /* Load the binary. */
  if (macho)
    {
      exthead->binaryaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
	+ grub_xnu_heap_will_be_at;
      exthead->binarysize = machosize;
      if (grub_xnu_is_64bit)
	err = grub_macho_readfile64 (macho, buf);
      else
	err = grub_macho_readfile32 (macho, buf);
      if (err)
	{
	  grub_macho_close (macho);
	  return err;
	}
      grub_macho_close (macho);
      buf += machosize;
    }
  grub_errno = GRUB_ERR_NONE;

  /* Load the plist. */
  if (infoplist)
    {
      exthead->infoplistaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
	+ grub_xnu_heap_will_be_at;
      exthead->infoplistsize = infoplistsize + 1;
      if (grub_file_read (infoplist, buf, infoplistsize)
	  != (grub_ssize_t) (infoplistsize))
	{
	  grub_file_close (infoplist);
	  grub_error_push ();
	  return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s: ",
			     infoplistname);
	}
      grub_file_close (infoplist);
      buf[infoplistsize] = 0;
      buf += infoplistsize + 1;
    }
  grub_errno = GRUB_ERR_NONE;

  exthead->nameaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
    + grub_xnu_heap_will_be_at;
  exthead->namesize = namelen + 1;
  grub_memcpy (buf, name, namelen);
  buf[namelen] = 0;
  buf += namelen + 1;

  /* Announce to kernel */
  return grub_xnu_register_memory ("Driver-", &driversnum, exthead,
				   neededspace);
}