示例#1
0
/* Opens 'filename' with compression filters disabled. Optionally disables the
   PUBKEY filter (that insists upon properly signed files) as well.  PUBKEY
   filter is restored before the function returns. */
static grub_file_t
open_envblk_file (char *filename, int untrusted)
{
  grub_file_t file;
  char *buf = 0;

  if (! filename)
    {
      const char *prefix;
      int len;

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

      len = grub_strlen (prefix);
      buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG));
      if (! buf)
        return 0;
      filename = buf;

      grub_strcpy (filename, prefix);
      filename[len] = '/';
      grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
    }

  /* The filters that are disabled will be re-enabled by the call to
     grub_file_open() after this particular file is opened. */
  grub_file_filter_disable_compression ();
  if (untrusted)
    grub_file_filter_disable_pubkey ();

  file = grub_file_open (filename);

  grub_free (buf);
  return file;
}
示例#2
0
文件: linux.c 项目: alex1818/grub
static grub_err_t
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
                 int argc, char *argv[])
{
    grub_file_t *files = 0;
    int i, nfiles = 0;
    grub_size_t size = 0;
    grub_uint8_t *ptr;

    if (argc == 0)
    {
        grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
        goto fail;
    }

    if (!loaded)
    {
        grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
        goto fail;
    }

    files = grub_zalloc (argc * sizeof (files[0]));
    if (!files)
        goto fail;

    for (i = 0; i < argc; i++)
    {
        grub_file_filter_disable_compression ();
        files[i] = grub_file_open (argv[i]);
        if (! files[i])
            goto fail;
        nfiles++;
        size += ALIGN_UP (grub_file_size (files[i]), 4);
    }

    initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));

    if (!initrd_mem)
    {
        grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
        goto fail;
    }

    params->ramdisk_size = size;
    params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem;

    ptr = initrd_mem;

    for (i = 0; i < nfiles; i++)
    {
        grub_ssize_t cursize = grub_file_size (files[i]);
        if (grub_file_read (files[i], ptr, cursize) != cursize)
        {
            if (!grub_errno)
                grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
                            argv[i]);
            goto fail;
        }
        grub_tpm_measure (ptr, cursize, GRUB_INITRD_PCR);
        ptr += cursize;
        grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
        ptr += ALIGN_UP_OVERHEAD (cursize, 4);
    }

    params->ramdisk_size = size;

fail:
    for (i = 0; i < nfiles; i++)
        grub_file_close (files[i]);
    grub_free (files);

    if (initrd_mem && grub_errno)
        grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size));

    return grub_errno;
}
示例#3
0
static void
read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
{
  static char buf[BUF_SIZE];
  grub_file_t file;
  grub_off_t ofs, len;

  if ((pathname[0] == '-') && (pathname[1] == 0))
    {
      grub_device_t dev;

      dev = grub_device_open (0);
      if ((! dev) || (! dev->disk))
        grub_util_error (_("can\'t open device"));

      grub_util_info ("total sectors : %lld",
                      (unsigned long long) dev->disk->total_sectors);

      if (! leng)
        leng = (dev->disk->total_sectors << GRUB_DISK_SECTOR_BITS) - skip;

      while (leng)
        {
          grub_size_t len;

          len = (leng > BUF_SIZE) ? BUF_SIZE : leng;

          if (grub_disk_read (dev->disk, 0, skip, len, buf))
            grub_util_error (_("disk read fails at offset %lld, length %d"),
                             skip, len);

          if (hook (skip, buf, len))
            break;

          skip += len;
          leng -= len;
        }

      grub_device_close (dev);
      return;
    }

  grub_file_filter_disable_compression ();
  file = grub_file_open (pathname);
  if (!file)
    {
      grub_util_error (_("cannot open file %s:%s"), pathname,
		       grub_errmsg);
      return;
    }

  grub_util_info ("file size : %lld", (unsigned long long) file->size);

  if (skip > file->size)
    {
      grub_util_error (_("invalid skip value %lld"), (unsigned long long) skip);
      return;
    }

  ofs = skip;
  len = file->size - skip;
  if ((leng) && (leng < len))
    len = leng;

  file->offset = skip;

  while (len)
    {
      grub_ssize_t sz;

      sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len);
      if (sz < 0)
	{
	  grub_util_error (_("read error at offset %llu: %s"), ofs,
			   grub_errmsg);
	  break;
	}

      if ((sz == 0) || (hook (ofs, buf, sz)))
	break;

      ofs += sz;
      len -= sz;
    }

  grub_file_close (file);
}
示例#4
0
文件: ls.c 项目: 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;
}
示例#5
0
文件: ls.c 项目: hisilicon/grub
/* Helper for grub_ls_list_files.  */
static int
print_files_long (const char *filename, const struct grub_dirhook_info *info,
		  void *data)
{
  struct grub_ls_list_files_ctx *ctx = data;

  if ((! ctx->all) && (filename[0] == '.'))
    return 0;

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

      if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/')
	pathname = grub_xasprintf ("%s%s", ctx->dirname, filename);
      else
	pathname = grub_xasprintf ("%s/%s", ctx->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 (! ctx->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 (ctx->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;
}
示例#6
0
static grub_err_t
grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
		 int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_ssize_t size;
  void *module = NULL;
  grub_addr_t target;
  grub_err_t err;
  int nounzip = 0;
  grub_uint64_t lowest_addr = 0;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  if (grub_strcmp (argv[0], "--nounzip") == 0)
    {
      argv++;
      argc--;
      nounzip = 1;
    }

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  if (!grub_multiboot_relocator)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
		       N_("you need to load the kernel first"));

  if (nounzip)
    grub_file_filter_disable_compression ();

  file = grub_file_open (argv[0]);
  if (! file)
    return grub_errno;

#ifndef GRUB_USE_MULTIBOOT2
  lowest_addr = 0x100000;
  if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL)
    lowest_addr = ALIGN_UP (highest_load + 1048576, 4096);
#endif

  size = grub_file_size (file);
  if (size)
  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
					    lowest_addr, (0xffffffff - size) + 1,
					    size, MULTIBOOT_MOD_ALIGN,
					    GRUB_RELOCATOR_PREFERENCE_NONE, 1);
    if (err)
      {
	grub_file_close (file);
	return err;
      }
    module = get_virtual_current_address (ch);
    target = get_physical_target_address (ch);
  }
  else
    {
      module = 0;
      target = 0;
    }

  err = grub_multiboot_add_module (target, size, argc - 1, argv + 1);
  if (err)
    {
      grub_file_close (file);
      return err;
    }

  if (size && grub_file_read (file, module, size) != size)
    {
      grub_file_close (file);
      if (!grub_errno)
	grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
		    argv[0]);
      return grub_errno;
    }

  /* Begin TCG Extension */
  DEBUG_PRINT( ("measured multiboot module: %s \n", argv[0]) );
  grub_TPM_measure_buffer( module, size, TPM_LOADER_MEASUREMENT_PCR );
  /* End TCG Extension */

  grub_file_close (file);
  return GRUB_ERR_NONE;
}
示例#7
0
文件: search.c 项目: crawford/grub
/* Helper for FUNC_NAME.  */
static int
iterate_device (const char *name, void *data)
{
  struct search_ctx *ctx = data;
  int found = 0;

  /* Skip floppy drives when requested.  */
  if (ctx->no_floppy &&
      name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
    return 0;

#ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp
#else
#define compare_fn grub_strcmp
#endif

#ifdef DO_SEARCH_FILE
    {
      char *buf;
      grub_file_t file;

      buf = grub_xasprintf ("(%s)%s", name, ctx->key);
      if (! buf)
	return 1;

      grub_file_filter_disable_compression ();
      file = grub_file_open (buf);
      if (file)
	{
	  found = 1;
	  grub_file_close (file);
	}
      grub_free (buf);
    }
#elif defined(DO_SEARCH_PART_UUID)
    {
      grub_device_t dev;
      char *quid;

      dev = grub_device_open (name);
      if (dev)
	{
	  if (grub_gpt_part_uuid (dev, &quid) == GRUB_ERR_NONE)
	    {
	      if (grub_strcasecmp (quid, ctx->key) == 0)
		    found = 1;

	      grub_free (quid);
	    }

	  grub_device_close (dev);
	}
    }
#elif defined(DO_SEARCH_PART_LABEL)
    {
      grub_device_t dev;
      char *quid;

      dev = grub_device_open (name);
      if (dev)
	{
	  if (grub_gpt_part_label (dev, &quid) == GRUB_ERR_NONE)
	    {
	      if (grub_strcmp (quid, ctx->key) == 0)
		    found = 1;

	      grub_free (quid);
	    }

	  grub_device_close (dev);
	}
    }
#else
    {
      /* SEARCH_FS_UUID or SEARCH_LABEL */
      grub_device_t dev;
      grub_fs_t fs;
      char *quid;

      dev = grub_device_open (name);
      if (dev)
	{
	  fs = grub_fs_probe (dev);

#ifdef DO_SEARCH_FS_UUID
#define read_fn uuid
#else
#define read_fn label
#endif

	  if (fs && fs->read_fn)
	    {
	      fs->read_fn (dev, &quid);

	      if (grub_errno == GRUB_ERR_NONE && quid)
		{
		  if (compare_fn (quid, ctx->key) == 0)
		    found = 1;

		  grub_free (quid);
		}
	    }

	  grub_device_close (dev);
	}
    }
#endif

  if (!ctx->is_cache && found && ctx->count == 0)
    {
      struct cache_entry *cache_ent;
      cache_ent = grub_malloc (sizeof (*cache_ent));
      if (cache_ent)
	{
	  cache_ent->key = grub_strdup (ctx->key);
	  cache_ent->value = grub_strdup (name);
	  if (cache_ent->value && cache_ent->key)
	    {
	      cache_ent->next = cache;
	      cache = cache_ent;
	    }
	  else
	    {
	      grub_free (cache_ent->value);
	      grub_free (cache_ent->key);
	      grub_free (cache_ent);
	      grub_errno = GRUB_ERR_NONE;
	    }
	}
      else
	grub_errno = GRUB_ERR_NONE;
    }

  if (found)
    {
      ctx->count++;
      if (ctx->var)
	grub_env_set (ctx->var, name);
      else
	grub_printf (" %s", name);
    }

  grub_errno = GRUB_ERR_NONE;
  return (found && ctx->var);
}
示例#8
0
grub_err_t
grub_initrd_init (int argc, char *argv[],
		  struct grub_linux_initrd_context *initrd_ctx)
{
  int i;
  int newc = 0;
  struct dir *root = 0;

  initrd_ctx->nfiles = 0;
  initrd_ctx->components = 0;

  initrd_ctx->components = grub_zalloc (argc
					* sizeof (initrd_ctx->components[0]));
  if (!initrd_ctx->components)
    return grub_errno;

  initrd_ctx->size = 0;

  for (i = 0; i < argc; i++)
    {
      const char *fname = argv[i];

      initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);

      if (grub_memcmp (argv[i], "newc:", 5) == 0)
	{
	  const char *ptr, *eptr;
	  ptr = argv[i] + 5;
	  while (*ptr == '/')
	    ptr++;
	  eptr = grub_strchr (ptr, ':');
	  if (eptr)
	    {
	      grub_file_filter_disable_compression ();
	      initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr);
	      if (!initrd_ctx->components[i].newc_name)
		{
		  grub_initrd_close (initrd_ctx);
		  return grub_errno;
		}
	      initrd_ctx->size
		+= ALIGN_UP (sizeof (struct newc_head)
			    + grub_strlen (initrd_ctx->components[i].newc_name),
			     4);
	      initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name,
					      &root, 0);
	      newc = 1;
	      fname = eptr + 1;
	    }
	}
      else if (newc)
	{
	  initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
					+ sizeof ("TRAILER!!!") - 1, 4);
	  free_dir (root);
	  root = 0;
	  newc = 0;
	}
      grub_file_filter_disable_compression ();
      initrd_ctx->components[i].file = grub_file_open (fname);
      if (!initrd_ctx->components[i].file)
	{
	  grub_initrd_close (initrd_ctx);
	  return grub_errno;
	}
      initrd_ctx->nfiles++;
      initrd_ctx->components[i].size
	= grub_file_size (initrd_ctx->components[i].file);
      initrd_ctx->size += initrd_ctx->components[i].size;
    }

  if (newc)
    {
      initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
				    + sizeof ("TRAILER!!!") - 1, 4);
      free_dir (root);
      root = 0;
    }
  
  return GRUB_ERR_NONE;
}
示例#9
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;
}
示例#10
0
文件: blocklist.c 项目: Arvian/GRUB2
static grub_err_t
grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
		    int argc, char **args)
{
  grub_file_t file;
  char buf[GRUB_DISK_SECTOR_SIZE];
  unsigned long start_sector = 0;
  unsigned num_sectors = 0;
  int num_entries = 0;
  grub_disk_addr_t part_start = 0;
  auto void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
			    unsigned length);
  auto void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
			     unsigned offset, unsigned length);

  void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
		       unsigned length)
    {
      if (num_sectors > 0)
	{
	  if (start_sector + num_sectors == sector
	      && offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
	    {
	      num_sectors++;
	      return;
	    }

	  print_blocklist (start_sector, num_sectors, 0, 0);
	  num_sectors = 0;
	}

      if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
	{
	  start_sector = sector;
	  num_sectors++;
	}
      else
	print_blocklist (sector, 0, offset, length);
    }

  void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
			unsigned offset, unsigned length)
    {
      if (num_entries++)
	grub_printf (",");

      grub_printf ("%llu", (unsigned long long) (sector - part_start));
      if (num > 0)
	grub_printf ("+%u", num);
      if (offset != 0 || length != 0)
	grub_printf ("[%u-%u]", offset, offset + length);
    }

  if (argc < 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  grub_file_filter_disable_compression ();
  file = grub_file_open (args[0]);
  if (! file)
    return grub_errno;

  if (! file->device->disk)
    return grub_error (GRUB_ERR_BAD_DEVICE,
		       "this command is available only for disk devices");

  part_start = grub_partition_get_start (file->device->disk->partition);

  file->read_hook = read_blocklist;

  while (grub_file_read (file, buf, sizeof (buf)) > 0)
    ;

  if (num_sectors > 0)
    print_blocklist (start_sector, num_sectors, 0, 0);

  grub_file_close (file);

  return grub_errno;
}
示例#11
0
void
grub_install_get_blocklist (grub_device_t root_dev,
			    const char *core_path, const char *core_img,
			    size_t core_size,
			    void (*callback) (grub_disk_addr_t sector,
					      unsigned offset,
					      unsigned length,
					      void *data),
			    void *hook_data)
{
  int i;
  char *tmp_img;
  char *core_path_dev;

  core_path_dev = grub_make_system_path_relative_to_its_root (core_path);

  /* Make sure that GRUB reads the identical image as the OS.  */
  tmp_img = xmalloc (core_size);

  for (i = 0; i < MAX_TRIES; i++)
    {
      grub_file_t file;

      grub_util_info ((i == 0) ? _("attempting to read the core image `%s' from GRUB")
		      : _("attempting to read the core image `%s' from GRUB again"),
		      core_path_dev);

      grub_disk_cache_invalidate_all ();

      grub_file_filter_disable_compression ();
      file = grub_file_open (core_path_dev);
      if (file)
	{
	  if (grub_file_size (file) != core_size)
	    grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)",
			    (int) grub_file_size (file), (int) core_size);
	  else if (grub_file_read (file, tmp_img, core_size)
		   != (grub_ssize_t) core_size)
	    grub_util_info ("succeeded in opening the core image but cannot read %d bytes",
			    (int) core_size);
	  else if (memcmp (core_img, tmp_img, core_size) != 0)
	    {
#if 0
	      FILE *dump;
	      FILE *dump2;

	      dump = fopen ("dump.img", "wb");
	      if (dump)
		{
		  fwrite (tmp_img, 1, core_size, dump);
		  fclose (dump);
		}

	      dump2 = fopen ("dump2.img", "wb");
	      if (dump2)
		{
		  fwrite (core_img, 1, core_size, dump2);
		  fclose (dump2);
		}

#endif
	      grub_util_info ("succeeded in opening the core image but the data is different");
	    }
	  else
	    {
	      grub_file_close (file);
	      break;
	    }

	  grub_file_close (file);
	}
      else
	grub_util_info ("couldn't open the core image");

      if (grub_errno)
	grub_util_info ("error message = %s", grub_errmsg);

      grub_errno = GRUB_ERR_NONE;
      grub_util_biosdisk_flush (root_dev->disk);
      sleep (1);
    }

  if (i == MAX_TRIES)
    grub_util_error (_("cannot read `%s' correctly"), core_path_dev);

  grub_file_t file;
  /* Now read the core image to determine where the sectors are.  */
  grub_file_filter_disable_compression ();
  file = grub_file_open (core_path_dev);
  if (! file)
    grub_util_error ("%s", grub_errmsg);

  file->read_hook = callback;
  file->read_hook_data = hook_data;
  if (grub_file_read (file, tmp_img, core_size) != (grub_ssize_t) core_size)
    grub_util_error ("%s", _("failed to read the sectors of the core image"));

  grub_file_close (file);
  free (tmp_img);

  free (core_path_dev);
}