示例#1
0
/* This is similar to grub_file_open. */
static grub_err_t
grub_mofile_open (struct grub_gettext_context *ctx,
		  const char *filename)
{
  struct header head;
  grub_err_t err;
  grub_file_t fd;

  /* Using fd_mo and not another variable because
     it's needed for grub_gettext_get_info.  */

  fd = grub_file_open (filename);

  if (!fd)
    return grub_errno;

  err = grub_gettext_pread (fd, &head, sizeof (head), 0);
  if (err)
    {
      grub_file_close (fd);
      return err;
    }

  if (head.magic != grub_cpu_to_le32_compile_time (MO_MAGIC_NUMBER))
    {
      grub_file_close (fd);
      return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			 "mo: invalid mo magic in file: %s", filename);
    }

  if (head.version != 0)
    {
      grub_file_close (fd);
      return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			 "mo: invalid mo version in file: %s", filename);
    }

  ctx->grub_gettext_offset_original = grub_le_to_cpu32 (head.offset_original);
  ctx->grub_gettext_offset_translation = grub_le_to_cpu32 (head.offset_translation);
  ctx->grub_gettext_max = grub_le_to_cpu32 (head.number_of_strings);
  for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log;
       ctx->grub_gettext_max_log++);

  ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max
					    * sizeof (ctx->grub_gettext_msg_list[0]));
  if (!ctx->grub_gettext_msg_list)
    {
      grub_file_close (fd);
      return grub_errno;
    }
  ctx->fd_mo = fd;
  if (grub_gettext != grub_gettext_translate)
    {
      grub_gettext_original = grub_gettext;
      grub_gettext = grub_gettext_translate;
    }
  return 0;
}
示例#2
0
static void
write_fat (FILE *in32, FILE *in64, FILE *out, const char *out_filename,
	   const char *name32, const char *name64)
{
  struct grub_macho_fat_header head;
  struct grub_macho_fat_arch arch32, arch64;
  grub_uint32_t size32, size64;
  char *buf;

  fseek (in32, 0, SEEK_END);
  size32 = ftell (in32);
  fseek (in32, 0, SEEK_SET);
  fseek (in64, 0, SEEK_END);
  size64 = ftell (in64);
  fseek (in64, 0, SEEK_SET);

  head.magic = grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC);
  head.nfat_arch = grub_cpu_to_le32_compile_time (2);
  arch32.cputype = grub_cpu_to_le32_compile_time (GRUB_MACHO_CPUTYPE_IA32);
  arch32.cpusubtype = grub_cpu_to_le32_compile_time (3);
  arch32.offset = grub_cpu_to_le32_compile_time (sizeof (head)
						 + sizeof (arch32)
						 + sizeof (arch64));
  arch32.size = grub_cpu_to_le32 (size32);
  arch32.align = 0;

  arch64.cputype = grub_cpu_to_le32_compile_time (GRUB_MACHO_CPUTYPE_AMD64);
  arch64.cpusubtype = grub_cpu_to_le32_compile_time (3);
  arch64.offset = grub_cpu_to_le32 (sizeof (head) + sizeof (arch32)
				    + sizeof (arch64) + size32);
  arch64.size = grub_cpu_to_le32 (size64);
  arch64.align = 0;
  if (fwrite (&head, 1, sizeof (head), out) != sizeof (head)
      || fwrite (&arch32, 1, sizeof (arch32), out) != sizeof (arch32)
      || fwrite (&arch64, 1, sizeof (arch64), out) != sizeof (arch64))
    {
      if (out_filename)
	grub_util_error ("cannot write to `%s': %s",
			 out_filename, strerror (errno));
      else
	grub_util_error ("cannot write to the stdout: %s", strerror (errno));
    }

  buf = xmalloc (size32);
  if (fread (buf, 1, size32, in32) != size32)
    grub_util_error (_("cannot read `%s': %s"), name32,
                     strerror (errno));
  if (fwrite (buf, 1, size32, out) != size32)
    {
      if (out_filename)
	grub_util_error ("cannot write to `%s': %s", 
			 out_filename, strerror (errno));
      else
	grub_util_error ("cannot write to the stdout: %s", strerror (errno));
    }
  free (buf);

  buf = xmalloc (size64);
  if (fread (buf, 1, size64, in64) != size64)
    grub_util_error (_("cannot read `%s': %s"), name64,
                     strerror (errno));
  if (fwrite (buf, 1, size64, out) != size64)
    {
      if (out_filename)
	grub_util_error ("cannot write to `%s': %s",
			 out_filename, strerror (errno));
      else
	grub_util_error ("cannot write to the stdout: %s", strerror (errno));
    }
  free (buf);
}
示例#3
0
文件: file.c 项目: Der-Jan/grub-zfs
static grub_err_t
grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
{
  grub_file_t file = 0;
  grub_elf_t elf = 0;
  grub_err_t err;
  int type = -1, i;
  int ret = 0;
  grub_macho_t macho = 0;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
  for (i = OPT_TYPE_MIN; i <= OPT_TYPE_MAX; i++)
    if (ctxt->state[i].set)
      {
	if (type == -1)
	  {
	    type = i;
	    continue;
	  }
	return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple types specified");
      }
  if (type == -1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no type specified");

  file = grub_file_open (args[0]);
  if (!file)
    return grub_errno;
  switch (type)
    {
    case IS_BIOS_BOOTSECTOR:
      {
	grub_uint16_t sig;
	if (grub_file_size (file) != 512)
	  break;
	if (grub_file_seek (file, 510) == (grub_size_t) -1)
	  break;
	if (grub_file_read (file, &sig, 2) != 2)
	  break;
	if (sig != grub_cpu_to_le16_compile_time (0xaa55))
	  break;
	ret = 1;
	break;
      }
    case IS_IA64_LINUX:
      {
	Elf64_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_ident[EI_CLASS] != ELFCLASS64
	    || ehdr.e_ident[EI_DATA] != ELFDATA2LSB
	    || ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_IA_64))
	  break;

	ret = 1;

	break;
      }

    case IS_SPARC64_LINUX:
      {
	Elf64_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_ident[EI_CLASS] != ELFCLASS64
	    || ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
	  break;

	if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_SPARCV9)
	    || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC))
	  break;

	ret = 1;

	break;
      }

    case IS_POWERPC_LINUX:
      {
	Elf32_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB
	    || (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_PPC)
		&& ehdr.e_machine !=
		grub_cpu_to_le16_compile_time (EM_PPC64)))
	  break;

	if (ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC)
	    && ehdr.e_type != grub_cpu_to_be16_compile_time (ET_DYN))
	  break;

	ret = 1;

	break;
      }

    case IS_MIPS_LINUX:
      {
	Elf32_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB
	    || ehdr.e_machine != grub_cpu_to_be16_compile_time (EM_MIPS)
	    || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC))
	  break;

	ret = 1;

	break;
      }

    case IS_X86_KNETBSD:
    case IS_X86_KNETBSD32:
    case IS_X86_KNETBSD64:
      {
	int is32, is64;

	elf = grub_elf_file (file, file->name);

	if (elf->ehdr.ehdr32.e_type != grub_cpu_to_le16_compile_time (ET_EXEC)
	    || elf->ehdr.ehdr32.e_ident[EI_DATA] != ELFDATA2LSB)
	  break;

	is32 = grub_elf_is_elf32 (elf);
	is64 = grub_elf_is_elf64 (elf);
	if (!is32 && !is64)
	  break;
	if (!is32 && type == IS_X86_KNETBSD32)
	  break;
	if (!is64 && type == IS_X86_KNETBSD64)
	  break;
	if (is64)
	  ret = grub_file_check_netbsd64 (elf);
	if (is32)
	  ret = grub_file_check_netbsd32 (elf);
	break;
      }

    case IS_X86_KFREEBSD:
    case IS_X86_KFREEBSD32:
    case IS_X86_KFREEBSD64:
      {
	Elf32_Ehdr ehdr;
	int is32, is64;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC)
	    || ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
	  break;

	if (ehdr.e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
	  break;

	is32 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_386)
		&& ehdr.e_ident[EI_CLASS] == ELFCLASS32);
	is64 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_X86_64)
		&& ehdr.e_ident[EI_CLASS] == ELFCLASS64);
	if (!is32 && !is64)
	  break;
	if (!is32 && (type == IS_X86_KFREEBSD32 || type == IS_X86_KNETBSD32))
	  break;
	if (!is64 && (type == IS_X86_KFREEBSD64 || type == IS_X86_KNETBSD64))
	  break;
	ret = 1;

	break;
      }


    case IS_MIPSEL_LINUX:
      {
	Elf32_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_MIPS)
	    || ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC))
	  break;

	ret = 1;

	break;
      }
    case IS_ARM_LINUX:
      {
	grub_uint32_t sig, sig_pi;
	if (grub_file_read (file, &sig_pi, 4) != 4)
	  break;
	/* Raspberry pi.  */
	if (sig_pi == grub_cpu_to_le32_compile_time (0xea000006))
	  {
	    ret = 1;
	    break;
	  }

	if (grub_file_seek (file, 0x24) == (grub_size_t) -1)
	  break;
	if (grub_file_read (file, &sig, 4) != 4)
	  break;
	if (sig == grub_cpu_to_le32_compile_time (0x016f2818))
	  {
	    ret = 1;
	    break;
	  }
	break;
      }
    case IS_ARM64_LINUX:
      {
	grub_uint32_t sig;

	if (grub_file_seek (file, 0x38) == (grub_size_t) -1)
	  break;
	if (grub_file_read (file, &sig, 4) != 4)
	  break;
	if (sig == grub_cpu_to_le32_compile_time (0x644d5241))
	  {
	    ret = 1;
	    break;
	  }
	break;
      }
    case IS_PAE_DOMU ... IS_DOM0:
      {
	struct grub_xen_file_info xen_inf;
	elf = grub_xen_file (file);
	if (!elf)
	  break;
	err = grub_xen_get_info (elf, &xen_inf);
	if (err)
	  break;
	/* Unfortuntely no way to check if kernel supports dom0.  */
	if (type == IS_DOM0)
	  ret = 1;
	if (type == IS_PAE_DOMU)
	  ret = (xen_inf.arch == GRUB_XEN_FILE_I386_PAE
		 || xen_inf.arch == GRUB_XEN_FILE_I386_PAE_BIMODE);
	if (type == IS_64_DOMU)
	  ret = (xen_inf.arch == GRUB_XEN_FILE_X86_64);
	break;
      }
    case IS_MULTIBOOT:
    case IS_MULTIBOOT2:
      {
	grub_uint32_t *buffer;
	grub_ssize_t len;
	grub_size_t search_size;
	grub_uint32_t *header;
	grub_uint32_t magic;
	grub_size_t step;

	if (type == IS_MULTIBOOT2)
	  {
	    search_size = 32768;
	    magic = grub_cpu_to_le32_compile_time (0xe85250d6);
	    step = 2;
	  }
	else
	  {
	    search_size = 8192;
	    magic = grub_cpu_to_le32_compile_time (0x1BADB002);
	    step = 1;
	  }

	buffer = grub_malloc (search_size);
	if (!buffer)
	  break;

	len = grub_file_read (file, buffer, search_size);
	if (len < 32)
	  {
	    grub_free (buffer);
	    break;
	  }

	/* Look for the multiboot header in the buffer.  The header should
	   be at least 12 bytes and aligned on a 4-byte boundary.  */
	for (header = buffer;
	     ((char *) header <=
	      (char *) buffer + len - (type == IS_MULTIBOOT2 ? 16 : 12))
	     || (header = 0); header += step)
	  {
	    if (header[0] == magic
		&& !(grub_le_to_cpu32 (header[0])
		     + grub_le_to_cpu32 (header[1])
		     + grub_le_to_cpu32 (header[2])
		     + (type == IS_MULTIBOOT2
			? grub_le_to_cpu32 (header[3]) : 0)))
	      break;
	  }

	if (header != 0)
	  ret = 1;
	grub_free (buffer);
	break;
      }
    case IS_X86_LINUX32:
    case IS_X86_LINUX:
      {
	struct linux_kernel_header lh;
	if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
	  break;
	if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
	  break;

	if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
	  break;

	/* FIXME: some really old kernels (< 1.3.73) will fail this.  */
	if (lh.header !=
	    grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE)
	    || grub_le_to_cpu16 (lh.version) < 0x0200)
	  break;

	if (type == IS_X86_LINUX)
	  {
	    ret = 1;
	    break;
	  }

	/* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and
	   still not support 32-bit boot.  */
	if (lh.header !=
	    grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE)
	    || grub_le_to_cpu16 (lh.version) < 0x0203)
	  break;

	if (!(lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
	  break;
	ret = 1;
	break;
      }
    case IS_HIBERNATED:
      {
	grub_uint8_t hibr_file_magic[4];
	if (grub_file_read (file, &hibr_file_magic, sizeof (hibr_file_magic))
	    != sizeof (hibr_file_magic))
	  break;
	if (grub_memcmp ("hibr", hibr_file_magic, sizeof (hibr_file_magic)) ==
	    0
	    || grub_memcmp ("HIBR", hibr_file_magic,
			    sizeof (hibr_file_magic)) == 0)
	  ret = 1;
	break;
      }
    case IS_XNU64:
    case IS_XNU32:
      {
	macho = grub_macho_open (args[0], (type == IS_XNU64));
	if (!macho)
	  break;
	/* FIXME: more checks?  */
	ret = 1;
	break;
      }
    case IS_XNU_HIBR:
      {
	struct grub_xnu_hibernate_header hibhead;
	if (grub_file_read (file, &hibhead, sizeof (hibhead))
	    != sizeof (hibhead))
	  break;
	if (hibhead.magic !=
	    grub_cpu_to_le32_compile_time (GRUB_XNU_HIBERNATE_MAGIC))
	  break;
	ret = 1;
	break;
      }
    case IS_32_EFI:
    case IS_64_EFI:
    case IS_IA_EFI:
    case IS_ARM64_EFI:
    case IS_ARM_EFI:
      {
	char signature[4];
	grub_uint32_t pe_offset;
	struct grub_pe32_coff_header coff_head;

	if (grub_file_read (file, signature, 2) != 2)
	  break;
	if (signature[0] != 'M' || signature[1] != 'Z')
	  break;
	if ((grub_ssize_t) grub_file_seek (file, 0x3c) == -1)
	  break;
	if (grub_file_read (file, &pe_offset, 4) != 4)
	  break;
	if ((grub_ssize_t) grub_file_seek (file, grub_le_to_cpu32 (pe_offset))
	    == -1)
	  break;
	if (grub_file_read (file, signature, 4) != 4)
	  break;
	if (signature[0] != 'P' || signature[1] != 'E'
	    || signature[2] != '\0' || signature[3] != '\0')
	  break;

	if (grub_file_read (file, &coff_head, sizeof (coff_head))
	    != sizeof (coff_head))
	  break;
	if (type == IS_32_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_I386))
	  break;
	if (type == IS_64_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_X86_64))
	  break;
	if (type == IS_IA_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_IA64))
	  break;
	if (type == IS_ARM64_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARM64))
	  break;
	if (type == IS_ARM_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARMTHUMB_MIXED))
	  break;
	if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI)
	  {
	    struct grub_pe64_optional_header o64;
	    if (grub_file_read (file, &o64, sizeof (o64)) != sizeof (o64))
	      break;
	    if (o64.magic !=
		grub_cpu_to_le16_compile_time (GRUB_PE32_PE64_MAGIC))
	      break;
	    if (o64.subsystem !=
		grub_cpu_to_le16_compile_time
		(GRUB_PE32_SUBSYSTEM_EFI_APPLICATION))
	      break;
	    ret = 1;
	    break;
	  }
	if (type == IS_32_EFI || type == IS_ARM_EFI)
	  {
	    struct grub_pe32_optional_header o32;
	    if (grub_file_read (file, &o32, sizeof (o32)) != sizeof (o32))
	      break;
	    if (o32.magic !=
		grub_cpu_to_le16_compile_time (GRUB_PE32_PE32_MAGIC))
	      break;
	    if (o32.subsystem !=
		grub_cpu_to_le16_compile_time
		(GRUB_PE32_SUBSYSTEM_EFI_APPLICATION))
	      break;
	    ret = 1;
	    break;
	  }
	break;
      }
    }

  if (elf)
    grub_elf_close (elf);
  else if (macho)
    grub_macho_close (macho);
  else if (file)
    grub_file_close (file);

  if (!ret && (grub_errno == GRUB_ERR_BAD_OS || grub_errno == GRUB_ERR_NONE))
    /* TRANSLATORS: it's a standalone boolean value,
       opposite of "true".  */
    grub_error (GRUB_ERR_TEST_FAILURE, N_("false"));
  return grub_errno;
}
示例#4
0
static struct grub_diskfilter_vg *
grub_mdraid_detect (grub_disk_t disk,
		    struct grub_diskfilter_pv_id *id,
		    grub_disk_addr_t *start_sector)
{
  grub_uint64_t size;
  grub_uint8_t minor_version;

  size = grub_disk_get_size (disk);

  /* Check for an 1.x superblock.
   * It's always aligned to a 4K boundary
   * and depending on the minor version it can be:
   * 0: At least 8K, but less than 12K, from end of device
   * 1: At start of device
   * 2: 4K from start of device.
   */

  for (minor_version = 0; minor_version < 3; ++minor_version)
    {
      grub_disk_addr_t sector = 0;
      struct grub_raid_super_1x sb;
      grub_uint16_t role;
      grub_uint32_t level;
      struct grub_diskfilter_vg *array;
      char *uuid;
	
      if (size == GRUB_DISK_SIZE_UNKNOWN && minor_version == 0)
	continue;
	
      switch (minor_version)
	{
	case 0:
	  sector = (size - 8 * 2) & ~(4 * 2 - 1);
	  break;
	case 1:
	  sector = 0;
	  break;
	case 2:
	  sector = 4 * 2;
	  break;
	}

      if (grub_disk_read (disk, sector, 0, sizeof (struct grub_raid_super_1x),
			  &sb))
	return NULL;

      if (sb.magic != grub_cpu_to_le32_compile_time (SB_MAGIC)
	  || grub_le_to_cpu64 (sb.super_offset) != sector)
	continue;

      if (sb.major_version != grub_cpu_to_le32_compile_time (1))
	/* Unsupported version.  */
	return NULL;

      level = grub_le_to_cpu32 (sb.level);

      /* Multipath.  */
      if ((int) level == -4)
	level = 1;

      if (level != 0 && level != 1 && level != 4 &&
	  level != 5 && level != 6 && level != 10)
	{
	  grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		      "Unsupported RAID level: %d", sb.level);
	  return NULL;
	}

      if (grub_le_to_cpu32 (sb.dev_number) >=
	  grub_le_to_cpu32 (sb.max_dev))
	/* Spares aren't implemented.  */
	return NULL;

      if (grub_disk_read (disk, sector, 
			  (char *) &sb.dev_roles[grub_le_to_cpu32 (sb.dev_number)]
			  - (char *) &sb,
			  sizeof (role), &role))
	return NULL;

      if (grub_le_to_cpu16 (role)
	  >= grub_le_to_cpu32 (sb.raid_disks))
	/* Spares aren't implemented.  */
	return NULL;

      id->uuidlen = 0;
      id->id = grub_le_to_cpu16 (role);

      uuid = grub_malloc (16);
      if (!uuid)
	return NULL;

      grub_memcpy (uuid, sb.set_uuid, 16);

      *start_sector = grub_le_to_cpu64 (sb.data_offset);

      array = grub_diskfilter_make_raid (16, uuid,
					 grub_le_to_cpu32 (sb.raid_disks),
					 sb.set_name,
					 (sb.size)
					 ? grub_le_to_cpu64 (sb.size) 
					 : grub_le_to_cpu64 (sb.data_size),
					 grub_le_to_cpu32 (sb.chunksize),
					 grub_le_to_cpu32 (sb.layout),
					 grub_le_to_cpu32 (sb.level));

      return array;
    }

  /* not 1.x raid.  */
  return NULL;
}
示例#5
0
static grub_err_t 
hfsplus_open_compressed_real (struct grub_hfsplus_file *node)
{
  grub_err_t err;
  struct grub_hfsplus_btnode *attr_node;
  grub_off_t attr_off;
  struct grub_hfsplus_key_internal key;
  struct grub_hfsplus_attr_header *attr_head;
  struct grub_hfsplus_compress_attr *cmp_head;
#define c grub_cpu_to_be16_compile_time
  const grub_uint16_t compress_attr_name[] =
    {
      c('c'), c('o'), c('m'), c('.'), c('a'), c('p'), c('p'), c('l'), c('e'),
      c('.'), c('d'), c('e'), c('c'), c('m'), c('p'), c('f'), c('s') };
#undef c
  if (node->size)
    return 0;

  key.attrkey.cnid = node->fileid;
  key.attrkey.namelen = sizeof (compress_attr_name) / sizeof (compress_attr_name[0]);
  key.attrkey.name = compress_attr_name;

  err = grub_hfsplus_btree_search (&node->data->attr_tree, &key,
				   grub_hfsplus_cmp_attrkey,
				   &attr_node, &attr_off);
  if (err || !attr_node)
    {
      grub_errno = 0;
      return 0;
    }

  attr_head = (struct grub_hfsplus_attr_header *)
    ((char *) grub_hfsplus_btree_recptr (&node->data->attr_tree,
					 attr_node, attr_off)
     + sizeof (struct grub_hfsplus_attrkey) + sizeof (compress_attr_name));
  if (attr_head->type != 0x10
      || !(attr_head->size & grub_cpu_to_be64_compile_time(~0xfULL)))
    {
      grub_free (attr_node);
      return 0;
    }
  cmp_head = (struct grub_hfsplus_compress_attr *) (attr_head + 1);
  if (cmp_head->magic != grub_cpu_to_be32_compile_time (0x66706d63))
    {
      grub_free (attr_node);
      return 0;
    }
  node->size = grub_le_to_cpu32 (cmp_head->uncompressed_inline_size);

  if (cmp_head->type == grub_cpu_to_le32_compile_time (HFSPLUS_COMPRESSION_RESOURCE))
    {
      grub_uint32_t index_size;
      node->compressed = 2;

      if (grub_hfsplus_read_file (node, 0, 0,
				  0x104, sizeof (index_size),
				  (char *) &index_size)
	  != 4)
	{
	  node->compressed = 0;
	  grub_free (attr_node);
	  grub_errno = 0;
	  return 0;
	}
      node->compress_index_size = grub_le_to_cpu32 (index_size);
      node->compress_index = grub_malloc (node->compress_index_size
					  * sizeof (node->compress_index[0]));
      if (!node->compress_index)
	{
	  node->compressed = 0;
	  grub_free (attr_node);
	  return grub_errno;
	}
      if (grub_hfsplus_read_file (node, 0, 0,
				  0x104 + sizeof (index_size),
				  node->compress_index_size
				  * sizeof (node->compress_index[0]),
				  (char *) node->compress_index)
	  != (grub_ssize_t) (node->compress_index_size
			     * sizeof (node->compress_index[0])))
	{
	  node->compressed = 0;
	  grub_free (attr_node);
	  grub_free (node->compress_index);
	  grub_errno = 0;
	  return 0;
	}

      node->cbuf_block = -1;

      node->cbuf = grub_malloc (HFSPLUS_COMPRESS_BLOCK_SIZE);
      grub_free (attr_node);
      if (!node->cbuf)
	{
	  node->compressed = 0;
	  grub_free (node->compress_index);
	  return grub_errno;
	}
      return 0;
    }
  if (cmp_head->type != HFSPLUS_COMPRESSION_INLINE)
    {
      grub_free (attr_node);
      return 0;
    }

  node->cbuf = grub_malloc (node->size);
  if (!node->cbuf)
    return grub_errno;

  if (grub_zlib_decompress ((char *) (cmp_head + 1),
			    grub_cpu_to_be64 (attr_head->size)
			    - sizeof (*cmp_head), 0,
			    node->cbuf, node->size) < 0)
    return grub_errno;
  node->compressed = 1;
  return 0;
}