Пример #1
0
Файл: compat.c Проект: xk/bits
void iterate_directory(const char *dirname, int (*callback)(const char *filename, const struct grub_dirhook_info *info))
{
    char *device_name;
    grub_device_t device;
    grub_errno = GRUB_ERR_NONE;
    device_name = grub_file_get_device_name(dirname);
    device = grub_device_open(device_name);
    if (device) {
        grub_fs_t fs = grub_fs_probe(device);
        if (fs)
            fs->dir(device, dirname, callback);
        grub_device_close(device);
    }
    grub_free(device_name);
}
Пример #2
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;
}
Пример #3
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);
  }
Пример #4
0
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;
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
0
Файл: ls.c Проект: Arvian/GRUB2
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;

  auto int print_files (const char *filename,
			const struct grub_dirhook_info *info);
  auto int print_files_long (const char *filename,
			     const struct grub_dirhook_info *info);

  int print_files (const char *filename, const struct grub_dirhook_info *info)
    {
      if (all || filename[0] != '.')
	grub_printf ("%s%s ", filename, info->dir ? "/" : "");

      return 0;
    }

  int print_files_long (const char *filename,
			const struct grub_dirhook_info *info)
    {
      if ((! all) && (filename[0] == '.'))
	return 0;

      if (! info->dir)
	{
	  grub_file_t file;
	  char *pathname;

	  if (dirname[grub_strlen (dirname) - 1] == '/')
	    pathname = grub_xasprintf ("%s%s", dirname, filename);
	  else
	    pathname = grub_xasprintf ("%s/%s", dirname, filename);

	  if (!pathname)
	    return 1;

	  /* XXX: For ext2fs symlinks are detected as files while they
	     should be reported as directories.  */
	  grub_file_filter_disable_compression ();
	  file = grub_file_open (pathname);
	  if (! file)
	    {
	      grub_errno = 0;
	      grub_free (pathname);
	      return 0;
	    }

	  if (! human)
	    grub_printf ("%-12llu", (unsigned long long) file->size);
	  else
	    {
	      grub_uint64_t fsize = file->size * 100ULL;
	      grub_uint64_t fsz = file->size;
	      int units = 0;
	      char buf[20];

	      while (fsz / 1024)
		{
		  fsize = (fsize + 512) / 1024;
		  fsz /= 1024;
		  units++;
		}

	      if (units)
		{
		  grub_uint64_t whole, fraction;

		  whole = grub_divmod64 (fsize, 100, &fraction);
		  grub_snprintf (buf, sizeof (buf),
				 "%" PRIuGRUB_UINT64_T
				 ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction,
				 grub_human_sizes[units]);
		  grub_printf ("%-12s", buf);
		}
	      else
		grub_printf ("%-12llu", (unsigned long long) file->size);

	    }
	  grub_file_close (file);
	  grub_free (pathname);
	}
      else
	grub_printf ("%-12s", _("DIR"));

      if (info->mtimeset)
	{
	  struct grub_datetime datetime;
	  grub_unixtime2datetime (info->mtime, &datetime);
	  if (human)
	    grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ",
			 datetime.year, datetime.month, datetime.day,
			 datetime.hour, datetime.minute,
			 datetime.second,
			 grub_get_weekday_name (&datetime));
	  else
	    grub_printf (" %04d%02d%02d%02d%02d%02d ",
			 datetime.year, datetime.month,
			 datetime.day, datetime.hour,
			 datetime.minute, datetime.second);
	}
      grub_printf ("%s%s\n", filename, info->dir ? "/" : "");

      return 0;
    }

  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)
    {
      if (longlist)
	(fs->dir) (dev, path, print_files_long);
      else
	(fs->dir) (dev, path, print_files);

      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);
	  else
	    print_files (p, &info);

	  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;
}