Exemplo n.º 1
0
Arquivo: boot.c Projeto: Arvian/GRUB2
/* Register a preboot hook. */
struct grub_preboot *
grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int flags),
				   grub_err_t (*preboot_rest_func) (void),
				   grub_loader_preboot_hook_prio_t prio)
{
  struct grub_preboot *cur, *new_preboot;

  if (! preboot_func && ! preboot_rest_func)
    return 0;

  new_preboot = (struct grub_preboot *)
    grub_malloc (sizeof (struct grub_preboot));
  if (! new_preboot)
    return 0;

  new_preboot->preboot_func = preboot_func;
  new_preboot->preboot_rest_func = preboot_rest_func;
  new_preboot->prio = prio;

  for (cur = preboots_head; cur && cur->prio > prio; cur = cur->next);

  if (cur)
    {
      new_preboot->next = cur;
      new_preboot->prev = cur->prev;
      cur->prev = new_preboot;
    }
  else
    {
      new_preboot->next = 0;
      new_preboot->prev = preboots_tail;
      preboots_tail = new_preboot;
    }
  if (new_preboot->prev)
    new_preboot->prev->next = new_preboot;
  else
    preboots_head = new_preboot;

  return new_preboot;
}
Exemplo n.º 2
0
Arquivo: ofdisk.c Projeto: flihp/grub2
static void
insert_bootpath (void)
{
  char *bootpath;
  grub_ssize_t bootpath_size;
  char *type;

  if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath",
					 &bootpath_size)
      || bootpath_size <= 0)
    {
      /* Should never happen.  */
      grub_printf ("/chosen/bootpath property missing!\n");
      return;
    }

  bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
  if (! bootpath)
    {
      grub_print_error ();
      return;
    }
  grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath,
                              (grub_size_t) bootpath_size + 1, 0);
  bootpath[bootpath_size] = '\0';

  /* Transform an OF device path to a GRUB path.  */

  type = grub_ieee1275_get_device_type (bootpath);
  if (!(type && grub_strcmp (type, "network") == 0))
    {
      struct ofdisk_hash_ent *op;
      char *device = grub_ieee1275_get_devname (bootpath);
      op = ofdisk_hash_add (device, NULL);
      op->is_boot = 1;
    }
  grub_free (type);
  grub_free (bootpath);
}
Exemplo n.º 3
0
static char *
grub_gettext_getstring_from_position (int position)
{
  int internal_position;
  int length, offset;
  char *original;

  /* Get position for string i.  */
  internal_position = grub_gettext_offsetoriginal + (position * 8);

  /* Get the length of the string i.  */
  grub_gettext_pread (fd_mo, (char *) &length, 4, internal_position);

  /* Get the offset of the string i.  */
  grub_gettext_pread (fd_mo, (char *) &offset, 4, internal_position + 4);

  /* Get the string i.  */
  original = grub_malloc (length + 1);
  grub_gettext_getstring_from_offset (offset, length, original);

  return original;
}
Exemplo n.º 4
0
char *
grub_legacy_escape (const char *in, grub_size_t len)
{
  char *ptr;
  char *ret;
  char saved;
  int overhead = 0;

  for (ptr = (char*)in; ptr < in + len && *ptr; ptr++)
    if (*ptr == '\'')
      overhead += 3;
  ret = grub_malloc (ptr - in + overhead + 1);
  if (!ret)
    return NULL;

  ptr = (char*)in;
  saved = ptr[len];
  ptr[len] = '\0';
  grub_strchrsub (ret, ptr, '\'', "'\\''");
  ptr[len] = saved;
  return ret;
}
Exemplo n.º 5
0
static char *
grub_cpio_get_link_target (struct grub_archelp_data *data)
{
  char *ret;
  grub_err_t err;

  if (data->size == 0)
    return grub_strdup ("");
  ret = grub_malloc (data->size + 1);
  if (!ret)
    return NULL;

  err = grub_disk_read (data->disk, 0, data->dofs, data->size, 
			ret);
  if (err)
    {
      grub_free (ret);
      return NULL;
    }
  ret[data->size] = '\0';
  return ret;
}
Exemplo n.º 6
0
/* Duplicate a device path.  */
static grub_efi_device_path_t *
duplicate_device_path (const grub_efi_device_path_t *dp)
{
  grub_efi_device_path_t *p;
  grub_size_t total_size = 0;

  for (p = (grub_efi_device_path_t *) dp;
       ;
       p = GRUB_EFI_NEXT_DEVICE_PATH (p))
    {
      total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
	break;
    }

  p = grub_malloc (total_size);
  if (! p)
    return 0;

  grub_memcpy (p, dp, total_size);
  return p;
}
Exemplo n.º 7
0
Arquivo: ext2.c Projeto: TemmeR/grub2
static char *
grub_ext2_read_symlink (grub_fshelp_node_t node)
{
  char *symlink;
  struct grub_fshelp_node *diro = node;

  if (! diro->inode_read)
    {
      grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
      if (grub_errno)
	return 0;
    }

  symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
  if (! symlink)
    return 0;

  /* If the filesize of the symlink is bigger than
     60 the symlink is stored in a separate block,
     otherwise it is stored in the inode.  */
  if (grub_le_to_cpu32 (diro->inode.size) <= 60)
    grub_strncpy (symlink,
		  diro->inode.symlink,
		  grub_le_to_cpu32 (diro->inode.size));
  else
    {
      grub_ext2_read_file (diro, 0, 0,
			   grub_le_to_cpu32 (diro->inode.size),
			   symlink);
      if (grub_errno)
	{
	  grub_free (symlink);
	  return 0;
	}
    }

  symlink[grub_le_to_cpu32 (diro->inode.size)] = '\0';
  return symlink;
}
Exemplo n.º 8
0
static int
grub_affs_iterate_dir (grub_fshelp_node_t dir,
		       int NESTED_FUNC_ATTR
		       (*hook) (const char *filename,
				enum grub_fshelp_filetype filetype,
				grub_fshelp_node_t node))
{
  int i;
  struct grub_affs_file file;
  struct grub_fshelp_node *node = 0;
  struct grub_affs_data *data = dir->data;
  grub_uint32_t *hashtable;

  auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
						   int size, int type);

  int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
					      int size, int type)
    {
      node = grub_malloc (sizeof (*node));
      if (!node)
	{
	  grub_free (hashtable);
	  return 1;
	}

      node->data = data;
      node->size = size;
      node->block = block;
      node->parent = grub_be_to_cpu32 (file.parent);

      if (hook (name, type, node))
	{
	  grub_free (hashtable);
	  return 1;
	}
      return 0;
    }
Exemplo n.º 9
0
grub_device_t
grub_device_open (const char *name)
{
  grub_device_t dev = 0;

  if (! name)
    {
      name = grub_env_get ("root");
      if (name == NULL || *name == '\0')
	{
	  grub_error (GRUB_ERR_BAD_DEVICE,  N_("variable `%s' isn't set"), "root");
	  goto fail;
	}
    }

  dev = grub_malloc (sizeof (*dev));
  if (! dev)
    goto fail;

  dev->net = NULL;
  /* Try to open a disk.  */
  dev->disk = grub_disk_open (name);
  if (dev->disk)
    return dev;
  if (grub_net_open && grub_errno == GRUB_ERR_UNKNOWN_DEVICE)
    {
      grub_errno = GRUB_ERR_NONE;
      dev->net = grub_net_open (name); 
    }

  if (dev->net)
    return dev;

 fail:
  grub_free (dev);

  return 0;
}
Exemplo n.º 10
0
static struct grub_font_glyph *
ascii_glyph_lookup (grub_uint32_t code)
{
#if HAVE_FONT_SOURCE
  static int ascii_failback_initialized = 0;

  if (code >= 0x80)
    return NULL;

  if (ascii_failback_initialized == 0)
    {
      int current;
      for (current = 0; current < 0x80; current++)
	{
	  ascii_font_glyph[current] =
	    grub_malloc (sizeof (struct grub_font_glyph) + ASCII_BITMAP_SIZE);

	  ascii_font_glyph[current]->width = 8;
	  ascii_font_glyph[current]->height = 16;
	  ascii_font_glyph[current]->offset_x = 0;
	  ascii_font_glyph[current]->offset_y = -2;
	  ascii_font_glyph[current]->device_width = 8;
	  ascii_font_glyph[current]->font = NULL;

	  grub_memcpy (ascii_font_glyph[current]->bitmap,
		       &ascii_bitmaps[current * ASCII_BITMAP_SIZE],
		       ASCII_BITMAP_SIZE);
	}

      ascii_failback_initialized = 1;
    }

  return ascii_font_glyph[code];
#else
  (void) code;
  return NULL;
#endif
}
Exemplo n.º 11
0
grub_device_t
grub_device_open (const char *name)
{
  grub_disk_t disk = 0;
  grub_device_t dev = 0;

  if (! name)
    {
      name = grub_env_get ("root");
      if (*name == '\0')
	{
	  grub_error (GRUB_ERR_BAD_DEVICE, "no device is set");
	  goto fail;
	}
    }

  dev = grub_malloc (sizeof (*dev));
  if (! dev)
    goto fail;

  /* Try to open a disk.  */
  disk = grub_disk_open (name);
  if (! disk)
    goto fail;

  dev->disk = disk;
  dev->net = 0;	/* FIXME */

  return dev;

 fail:
  if (disk)
    grub_disk_close (disk);

  grub_free (dev);

  return 0;
}
Exemplo n.º 12
0
static char*
wildcard_escape (const char *s)
{
  int i;
  int len;
  char ch;
  char *p;

  len = grub_strlen (s);
  p = grub_malloc (len * 2 + 1);
  if (! p)
    return NULL;

  i = 0;
  while ((ch = *s++))
    {
      if (ch == '*' || ch == '\\' || ch == '?')
	p[i++] = '\\';
      p[i++] = ch;
    }
  p[i] = '\0';
  return p;
}
Exemplo n.º 13
0
static const char *
grub_gettext_gettranslation_from_position (int position)
{
  int offsettranslation;
  int internal_position;
  grub_uint32_t length, offset;
  char *translation;

  offsettranslation = grub_gettext_get_info (GETTEXT_OFFSET_TRANSLATION);

  internal_position = offsettranslation + position * 8;

  grub_gettext_pread (fd_mo, (char *) &length, 4, internal_position);
  length = grub_cpu_to_le32 (length);

  grub_gettext_pread (fd_mo, (char *) &offset, 4, internal_position + 4);
  offset = grub_cpu_to_le32 (offset);

  translation = grub_malloc (length + 1);
  grub_gettext_getstring_from_offset (offset, length, translation);

  return translation;
}
Exemplo n.º 14
0
/* Find the optimal number of pages for the memory map. Is it better to
   move this code to efi/mm.c?  */
static grub_efi_uintn_t
find_efi_mmap_size (void)
{
  static grub_efi_uintn_t mmap_size = 0;

  if (mmap_size != 0)
    return mmap_size;

  mmap_size = (1 << 12);
  while (1)
    {
      int ret;
      grub_efi_memory_descriptor_t *mmap;
      grub_efi_uintn_t desc_size;

      mmap = grub_malloc (mmap_size);
      if (! mmap)
	return 0;

      ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
      grub_free (mmap);

      if (ret < 0)
	grub_fatal ("cannot get memory map");
      else if (ret > 0)
	break;

      mmap_size += (1 << 12);
    }

  /* Increase the size a bit for safety, because GRUB allocates more on
     later, and EFI itself may allocate more.  */
  mmap_size += (1 << 12);

  mmap_size = page_align (mmap_size);
  return mmap_size;
}
Exemplo n.º 15
0
static grub_envblk_t
read_envblk_file (grub_file_t file)
{
  grub_off_t offset = 0;
  char *buf;
  grub_size_t size = grub_file_size (file);
  grub_envblk_t envblk;

  buf = grub_malloc (size);
  if (! buf)
    return 0;

  while (size > 0)
    {
      grub_ssize_t ret;

      ret = grub_file_read (file, buf + offset, size);
      if (ret <= 0)
        {
          grub_free (buf);
          return 0;
        }

      size -= ret;
      offset += ret;
    }

  envblk = grub_envblk_open (buf, offset);
  if (! envblk)
    {
      grub_free (buf);
      grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
      return 0;
    }

  return envblk;
}
Exemplo n.º 16
0
/* Try to load an icon for the specified CLASS_NAME in the directory DIR.
   Returns 0 if the icon could not be loaded, or returns a pointer to a new
   bitmap if it was successful.  */
static struct grub_video_bitmap *
try_loading_icon (grub_gfxmenu_icon_manager_t mgr,
                  const char *dir, const char *class_name)
{
  char *path, *ptr;

  path = grub_malloc (grub_strlen (dir) + grub_strlen (class_name)
		      + grub_strlen (icon_extension) + 3);
  if (! path)
    return 0;

  ptr = grub_stpcpy (path, dir);
  if (path == ptr || ptr[-1] != '/')
    *ptr++ = '/';
  ptr = grub_stpcpy (ptr, class_name);
  ptr = grub_stpcpy (ptr, icon_extension);
  *ptr = '\0';

  struct grub_video_bitmap *raw_bitmap;
  grub_video_bitmap_load (&raw_bitmap, path);
  grub_free (path);
  grub_errno = GRUB_ERR_NONE;  /* Critical to clear the error!!  */
  if (! raw_bitmap)
    return 0;

  struct grub_video_bitmap *scaled_bitmap;
  grub_video_bitmap_create_scaled (&scaled_bitmap,
                                   mgr->icon_width, mgr->icon_height,
                                   raw_bitmap,
                                   GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
  grub_video_bitmap_destroy (raw_bitmap);
  if (! scaled_bitmap)
    return 0;

  return scaled_bitmap;
}
Exemplo n.º 17
0
Arquivo: gpt.c Projeto: crawford/grub
grub_err_t
grub_gpt_part_label (grub_device_t device, char **label)
{
  struct grub_gpt_partentry entry;
  const grub_size_t name_len = ARRAY_SIZE (entry.name);
  const grub_size_t label_len = name_len * GRUB_MAX_UTF8_PER_UTF16 + 1;
  grub_size_t i;
  grub_uint8_t *end;

  if (grub_gpt_device_partentry (device, &entry))
    return grub_errno;

  *label = grub_malloc (label_len);
  if (!*label)
    return grub_errno;

  for (i = 0; i < name_len; i++)
    entry.name[i] = grub_le_to_cpu16 (entry.name[i]);

  end = grub_utf16_to_utf8 ((grub_uint8_t *) *label, entry.name, name_len);
  *end = '\0';

  return GRUB_ERR_NONE;
}
Exemplo n.º 18
0
Arquivo: elf.c Projeto: TemmeR/grub2
static grub_err_t
grub_elf32_load_phdrs (grub_elf_t elf)
{
  grub_ssize_t phdrs_size;

  phdrs_size = elf->ehdr.ehdr32.e_phnum * elf->ehdr.ehdr32.e_phentsize;

  grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n",
		(unsigned long long) elf->ehdr.ehdr32.e_phoff,
		(unsigned long) phdrs_size);

  elf->phdrs = grub_malloc (phdrs_size);
  if (! elf->phdrs)
    return grub_errno;

  if ((grub_file_seek (elf->file, elf->ehdr.ehdr32.e_phoff) == (grub_off_t) -1)
      || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
    {
      grub_error_push ();
      return grub_error (GRUB_ERR_READ_ERROR, "cannot read program headers");
    }

  return GRUB_ERR_NONE;
}
Exemplo n.º 19
0
/* The command to add and remove loopback devices.  */
static grub_err_t
grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args)
{
  struct grub_arg_list *state = state = cmd->state;
  grub_file_t file;
  struct grub_loopback *newdev;

  if (argc < 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");

  /* Check if `-d' was used.  */
  if (state[0].set)
      return delete_loopback (args[0]);

  if (argc < 2)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");

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

  /* First try to replace the old device.  */
  for (newdev = loopback_list; newdev; newdev = newdev->next)
    if (grub_strcmp (newdev->devname, args[0]) == 0)
      break;

  if (newdev)
    {
      char *newname = grub_strdup (args[1]);
      if (! newname)
	goto fail;

      grub_free (newdev->filename);
      newdev->filename = newname;
      grub_file_close (newdev->file);
      newdev->file = file;

      /* Set has_partitions when `--partitions' was used.  */
      newdev->has_partitions = state[1].set;

      return 0;
    }

  /* Unable to replace it, make a new entry.  */
  newdev = grub_malloc (sizeof (struct grub_loopback));
  if (! newdev)
    goto fail;

  newdev->devname = grub_strdup (args[0]);
  if (! newdev->devname)
    {
      grub_free (newdev);
      goto fail;
    }

  newdev->filename = grub_strdup (args[1]);
  if (! newdev->filename)
    {
      grub_free (newdev->devname);
      grub_free (newdev);
      goto fail;
    }

  newdev->file = file;

  /* Set has_partitions when `--partitions' was used.  */
  newdev->has_partitions = state[1].set;

  /* Add the new entry to the list.  */
  newdev->next = loopback_list;
  loopback_list = newdev;

  return 0;

fail:
  grub_file_close (file);
  return grub_errno;
}
Exemplo n.º 20
0
static struct grub_affs_data *
grub_affs_mount (grub_disk_t disk)
{
  struct grub_affs_data *data;
  grub_uint32_t *rootblock = 0;
  struct grub_affs_rblock *rblock;

  int checksum = 0;
  int checksumr = 0;
  int blocksize = 0;

  data = grub_malloc (sizeof (struct grub_affs_data));
  if (!data)
    return 0;

  /* Read the bootblock.  */
  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
		  &data->bblock);
  if (grub_errno)
    goto fail;

  /* Make sure this is an affs filesystem.  */
  if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3))
    {
      grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");
      goto fail;
    }

  /* Test if the filesystem is a OFS filesystem.  */
  if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS))
    {
      grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported");
      goto fail;
    }

  /* Read the bootblock.  */
  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
		  &data->bblock);
  if (grub_errno)
    goto fail;

  /* No sane person uses more than 8KB for a block.  At least I hope
     for that person because in that case this won't work.  */
  rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16);
  if (!rootblock)
    goto fail;

  rblock = (struct grub_affs_rblock *) rootblock;

  /* Read the rootblock.  */
  grub_disk_read (disk, grub_be_to_cpu32 (data->bblock.rootblock), 0,
		  GRUB_DISK_SECTOR_SIZE * 16, rootblock);
  if (grub_errno)
    goto fail;

  /* The filesystem blocksize is not stored anywhere in the filesystem
     itself.  One way to determine it is reading blocks for the
     rootblock until the checksum is correct.  */
  checksumr = grub_be_to_cpu32 (rblock->checksum);
  rblock->checksum = 0;
  for (blocksize = 0; blocksize < 8; blocksize++)
    {
      grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize;
      unsigned int i;

      for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++)
	checksum += grub_be_to_cpu32 (currblock[i]);

      if (checksumr == -checksum)
	break;
    }
  if (-checksum != checksumr)
    {
      grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined");
      goto fail;
    }
  blocksize++;

  data->blocksize = blocksize;
  data->disk = disk;
  data->htsize = grub_be_to_cpu32 (rblock->htsize);
  data->diropen.data = data;
  data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock);

  grub_free (rootblock);

  return data;

 fail:
  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");

  grub_free (data);
  grub_free (rootblock);
  return 0;
}
Exemplo n.º 21
0
	}

      node->data = data;
      node->size = size;
      node->block = block;
      node->parent = grub_be_to_cpu32 (file.parent);

      if (hook (name, type, node))
	{
	  grub_free (hashtable);
	  return 1;
	}
      return 0;
    }

  hashtable = grub_malloc (data->htsize * sizeof (*hashtable));
  if (!hashtable)
    return 1;

  grub_disk_read (data->disk, dir->block, GRUB_AFFS_HASHTABLE_OFFSET,
		  data->htsize * sizeof (*hashtable), (char *) hashtable);
  if (grub_errno)
    goto fail;

  /* Create the directory entries for `.' and `..'.  */
  if (grub_affs_create_node (".", dir->block, dir->size, GRUB_FSHELP_DIR))
    return 1;
  if (grub_affs_create_node ("..", dir->parent ? dir->parent : dir->block,
			     dir->size, GRUB_FSHELP_DIR))
    return 1;
Exemplo n.º 22
0
Arquivo: hfs.c Projeto: P4N74/radare2
/* Mount the filesystem on the disk DISK.  */
static struct grub_hfs_data *
grub_hfs_mount (grub_disk_t disk)
{
  struct grub_hfs_data *data;
  struct grub_hfs_catalog_key key;
  struct grub_hfs_dirrec dir;
  int first_block;

  struct
  {
    struct grub_hfs_node node;
    struct grub_hfs_treeheader head;
  } treehead;

  data = grub_malloc (sizeof (struct grub_hfs_data));
  if (!data)
    return 0;

  /* Read the superblock.  */
  if (grub_disk_read (disk, GRUB_HFS_SBLOCK, 0,
		      sizeof (struct grub_hfs_sblock), &data->sblock))
    goto fail;

  /* Check if this is a HFS filesystem.  */
  if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC)
    {
      grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem");
      goto fail;
    }

  /* Check if this is an embedded HFS+ filesystem.  */
  if (grub_be_to_cpu16 (data->sblock.embed_sig) == GRUB_HFS_EMBED_HFSPLUS_SIG)
    {
      grub_error (GRUB_ERR_BAD_FS, "embedded HFS+ filesystem");
      goto fail;
    }

  data->blksz = grub_be_to_cpu32 (data->sblock.blksz);
  data->disk = disk;

  /* Lookup the root node of the extent overflow tree.  */
  first_block = ((grub_be_to_cpu16 (data->sblock.extent_recs[0].first_block)
		  * GRUB_HFS_BLKS)
		 + grub_be_to_cpu16 (data->sblock.first_block));

  if (grub_disk_read (data->disk, first_block, 0,
		      sizeof (treehead), &treehead))
    goto fail;
  data->ext_root = grub_be_to_cpu32 (treehead.head.root_node);
  data->ext_size = grub_be_to_cpu16 (treehead.head.node_size);

  /* Lookup the root node of the catalog tree.  */
  first_block = ((grub_be_to_cpu16 (data->sblock.catalog_recs[0].first_block)
		  * GRUB_HFS_BLKS)
		 + grub_be_to_cpu16 (data->sblock.first_block));
  if (grub_disk_read (data->disk, first_block, 0,
		      sizeof (treehead), &treehead))
    goto fail;
  data->cat_root = grub_be_to_cpu32 (treehead.head.root_node);
  data->cat_size = grub_be_to_cpu16 (treehead.head.node_size);

  /* Lookup the root directory node in the catalog tree using the
     volume name.  */
  key.parent_dir = grub_cpu_to_be32 (1);
  key.strlen = data->sblock.volname[0];
  grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1));

  if (grub_hfs_find_node (data, (char *) &key, data->cat_root,
			  0, (char *) &dir, sizeof (dir)) == 0)
    {
      grub_error (GRUB_ERR_BAD_FS, "cannot find the HFS root directory");
      goto fail;
    }

  if (grub_errno)
    goto fail;

  data->rootdir = grub_be_to_cpu32 (dir.dirid);

  return data;
 fail:
  grub_free (data);

  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not a HFS filesystem");

  return 0;
}
Exemplo n.º 23
0
grub_err_t
grub_mmap_iterate (int (*hook) (grub_uint64_t, grub_uint64_t,
				grub_uint32_t, void *), void *closure)
{
  /* This function resolves overlapping regions and sorts the memory map.
     It uses scanline (sweeping) algorithm.
  */
  /* If same page is used by multiple types it's resolved
     according to priority:
     1 - free memory
     2 - memory usable by firmware-aware code
     3 - unusable memory
     4 - a range deliberately empty
  */
  int priority[GRUB_MACHINE_MEMORY_MAX_TYPE + 2] =
    {
#ifdef GRUB_MACHINE_MEMORY_AVAILABLE
      [GRUB_MACHINE_MEMORY_AVAILABLE] = 1,
#endif
#if defined (GRUB_MACHINE_MEMORY_RESERVED) && GRUB_MACHINE_MEMORY_RESERVED != GRUB_MACHINE_MEMORY_HOLE
      [GRUB_MACHINE_MEMORY_RESERVED] = 3,
#endif
#ifdef GRUB_MACHINE_MEMORY_ACPI
      [GRUB_MACHINE_MEMORY_ACPI] = 2,
#endif
#ifdef GRUB_MACHINE_MEMORY_CODE
      [GRUB_MACHINE_MEMORY_CODE] = 3,
#endif
#ifdef GRUB_MACHINE_MEMORY_NVS
      [GRUB_MACHINE_MEMORY_NVS] = 3,
#endif
      [GRUB_MACHINE_MEMORY_HOLE] = 4,
    };

  int i, k, done;

  struct grub_mmap_scan *scanline_events;
  struct grub_mmap_scan t;

  /* Previous scanline event. */
  grub_uint64_t lastaddr;
  int lasttype;
  /* Current scanline event. */
  int curtype;
  /* How many regions of given type overlap at current location? */
  int present[GRUB_MACHINE_MEMORY_MAX_TYPE + 2];
  /* Number of mmap chunks. */
  int mmap_num;
  struct grub_mmap_iterate_closure c;

#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
  struct grub_mmap_region *cur;
#endif

  mmap_num = 0;

#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
  for (cur = grub_mmap_overlays; cur; cur = cur->next)
    mmap_num++;
#endif

  grub_machine_mmap_iterate (count_hook, &mmap_num);

  /* Initialize variables. */
  grub_memset (present, 0, sizeof (present));
  scanline_events = (struct grub_mmap_scan *)
    grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num);

  if (! scanline_events)
    {
      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
			 "couldn't allocate space for new memory map");
    }

  i = 0;
#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
  /* Register scanline events. */
  for (cur = grub_mmap_overlays; cur; cur = cur->next)
    {
      scanline_events[i].pos = cur->start;
      scanline_events[i].type = 0;
      if (cur->type == GRUB_MACHINE_MEMORY_HOLE
	  || (cur->type >= 0 && cur->type <= GRUB_MACHINE_MEMORY_MAX_TYPE
	      && priority[cur->type]))
	scanline_events[i].memtype = cur->type;
      else
	scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
      i++;

      scanline_events[i].pos = cur->end;
      scanline_events[i].type = 1;
      scanline_events[i].memtype = scanline_events[i - 1].memtype;
      i++;
    }
#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */

  c.i = i;
  c.scanline_events = scanline_events;
  c.priority = priority;
  grub_machine_mmap_iterate (fill_hook, &c);

  /* Primitive bubble sort. It has complexity O(n^2) but since we're
     unlikely to have more than 100 chunks it's probably one of the
     fastest for one purpose. */
  done = 1;
  while (done)
    {
      done = 0;
      for (i = 0; i < 2 * mmap_num - 1; i++)
	if (scanline_events[i + 1].pos < scanline_events[i].pos
	    || (scanline_events[i + 1].pos == scanline_events[i].pos
		&& scanline_events[i + 1].type == 0
		&& scanline_events[i].type == 1))
	  {
	    t = scanline_events[i + 1];
	    scanline_events[i + 1] = scanline_events[i];
	    scanline_events[i] = t;
	    done = 1;
	  }
    }

  lastaddr = scanline_events[0].pos;
  lasttype = scanline_events[0].memtype;
  for (i = 0; i < 2 * mmap_num; i++)
    {
      /* Process event. */
      if (scanline_events[i].type)
	present[scanline_events[i].memtype]--;
      else
	present[scanline_events[i].memtype]++;

      /* Determine current region type. */
      curtype = -1;
      for (k = 0; k <= GRUB_MACHINE_MEMORY_MAX_TYPE + 1; k++)
	if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
	  curtype = k;

      /* Announce region to the hook if necessary. */
      if ((curtype == -1 || curtype != lasttype)
	  && lastaddr != scanline_events[i].pos
	  && lasttype != -1
	  && lasttype != GRUB_MACHINE_MEMORY_HOLE
	  && hook (lastaddr, scanline_events[i].pos - lastaddr, lasttype,
		   closure))
	{
	  grub_free (scanline_events);
	  return GRUB_ERR_NONE;
	}

      /* Update last values if necessary. */
      if (curtype == -1 || curtype != lasttype)
	{
	  lasttype = curtype;
	  lastaddr = scanline_events[i].pos;
	}
    }

  grub_free (scanline_events);
  return GRUB_ERR_NONE;
}
Exemplo n.º 24
0
grub_command_t
grub_register_command (const char *name,
		       grub_err_t (*func) (struct grub_arg_list *state,
					   int argc, char **args),
		       unsigned flags,
		       const char *summary,
		       const char *description,
		       const struct grub_arg_option *options)
{
  grub_command_t cmd, *p;

  cmd = (grub_command_t) grub_malloc (sizeof (*cmd));
  if (! cmd)
    return 0;

  cmd->name = grub_strdup (name);
  if (! cmd->name)
    {
      grub_free (cmd);
      return 0;
    }
  
  cmd->func = func;
  cmd->flags = flags;
  cmd->summary = summary;
  cmd->description = description;
  cmd->options = options;
  cmd->module_name = 0;

  /* Keep the list sorted for simplicity.  */
  p = &grub_command_list;
  while (*p)
    {
      if (grub_strcmp ((*p)->name, name) >= 0)
	break;

      p = &((*p)->next);
    }

  if (*p && grub_strcmp ((*p)->name, name) == 0)
    {
      grub_command_t q;

      q = *p;
      if (q->flags & GRUB_COMMAND_FLAG_NOT_LOADED)
	{
	  q->func = cmd->func;
	  q->flags = cmd->flags;
	  q->summary = cmd->summary;
	  q->description = cmd->description;
	  q->options = cmd->options;
	  grub_free (cmd->name);
	  grub_free (cmd->module_name);
	  grub_free (cmd);
	  cmd = q;
	}
      else
	{
	  grub_free (cmd->name);
	  grub_free (cmd);
	  cmd = 0;
	}
    }
  else
    {
      cmd->next = *p;
      *p = cmd;
    }

  return cmd;
}
Exemplo n.º 25
0
/* Creates new bitmap, saves created bitmap on success to *bitmap.  */
grub_err_t
grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
                          unsigned int width, unsigned int height,
                          enum grub_video_blit_format blit_format)
{
  struct grub_video_mode_info *mode_info;
  unsigned int size;

  if (!bitmap)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");

  *bitmap = 0;

  if (width == 0 || height == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");

  *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap));
  if (! *bitmap)
    return grub_errno;

  mode_info = &((*bitmap)->mode_info);

  /* Populate mode_info.  */
  mode_info->width = width;
  mode_info->height = height;
  mode_info->blit_format = blit_format;

  switch (blit_format)
    {
      case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB
                               | GRUB_VIDEO_MODE_TYPE_ALPHA;
        mode_info->bpp = 32;
        mode_info->bytes_per_pixel = 4;
        mode_info->number_of_colors = 256;
        mode_info->red_mask_size = 8;
        mode_info->red_field_pos = 0;
        mode_info->green_mask_size = 8;
        mode_info->green_field_pos = 8;
        mode_info->blue_mask_size = 8;
        mode_info->blue_field_pos = 16;
        mode_info->reserved_mask_size = 8;
        mode_info->reserved_field_pos = 24;
        break;

      case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
        mode_info->bpp = 24;
        mode_info->bytes_per_pixel = 3;
        mode_info->number_of_colors = 256;
        mode_info->red_mask_size = 8;
        mode_info->red_field_pos = 0;
        mode_info->green_mask_size = 8;
        mode_info->green_field_pos = 8;
        mode_info->blue_mask_size = 8;
        mode_info->blue_field_pos = 16;
        mode_info->reserved_mask_size = 0;
        mode_info->reserved_field_pos = 0;
        break;

      case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
        mode_info->bpp = 8;
        mode_info->bytes_per_pixel = 1;
        mode_info->number_of_colors = 256;
        mode_info->red_mask_size = 0;
        mode_info->red_field_pos = 0;
        mode_info->green_mask_size = 0;
        mode_info->green_field_pos = 0;
        mode_info->blue_mask_size = 0;
        mode_info->blue_field_pos = 0;
        mode_info->reserved_mask_size = 0;
        mode_info->reserved_field_pos = 0;
        break;

      default:
        grub_free (*bitmap);
        *bitmap = 0;

        return grub_error (GRUB_ERR_BAD_ARGUMENT,
                           "unsupported bitmap format");
    }

  mode_info->pitch = width * mode_info->bytes_per_pixel;

  /* Calculate size needed for the data.  */
  size = (width * mode_info->bytes_per_pixel) * height;

  (*bitmap)->data = grub_zalloc (size);
  if (! (*bitmap)->data)
    {
      grub_free (*bitmap);
      *bitmap = 0;

      return grub_errno;
    }

  return GRUB_ERR_NONE;
}
Exemplo n.º 26
0
static grub_err_t
grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
                    char *buf, grub_disk_addr_t sector, int size)
{
  int i, q, pos;
  int err[2], nerr;
  char *pbuf = 0, *qbuf = 0;

  size <<= GRUB_DISK_SECTOR_BITS;
  pbuf = grub_malloc (size);
  if (!pbuf)
    goto quit;

  qbuf = grub_malloc (size);
  if (!qbuf)
    goto quit;

  q = p + 1;
  if (q == (int) array->total_devs)
    q = 0;

  grub_memset (pbuf, 0, size);
  grub_memset (qbuf, 0, size);

  pos = q + 1;
  if (pos == (int) array->total_devs)
    pos = 0;

  nerr = 1;
  for (i = 0; i < (int) array->total_devs - 2; i++)
    {
      if (pos == disknr)
        err[0] = i;
      else
        {
          if ((array->device[pos]) &&
              (! grub_disk_read (array->device[pos], sector, 0, size, buf)))
            {
              grub_raid_block_xor (pbuf, buf, size);
              grub_raid_block_mul (raid6_table2[i][i], buf, size);
              grub_raid_block_xor (qbuf, buf, size);
            }
          else
            {
              if (nerr >= 2)
                goto quit;

              err[nerr++] = i;
              grub_errno = GRUB_ERR_NONE;
            }
        }

      pos++;
      if (pos == (int) array->total_devs)
        pos = 0;
    }

  if (nerr == 1)
    {
      if ((array->device[p]) &&
          (! grub_disk_read (array->device[p], sector, 0, size, buf)))
        {
          grub_raid_block_xor (buf, pbuf, size);
          goto quit;
        }

      if (! array->device[q])
        {
          grub_error (GRUB_ERR_READ_ERROR, "Not enough disk to restore");
          goto quit;
        }

      grub_errno = GRUB_ERR_NONE;
      if (grub_disk_read (array->device[q], sector, 0, size, buf))
        goto quit;

      grub_raid_block_xor (buf, qbuf, size);
      grub_raid_block_mul (raid6_table2[255 - err[0]][255 - err[0]], buf,
                           size);
    }
  else
    {
      grub_uint8_t c;

      if ((! array->device[p]) || (! array->device[q]))
        {
          grub_error (GRUB_ERR_READ_ERROR, "Not enough disk to restore");
          goto quit;
        }

      if (grub_disk_read (array->device[p], sector, 0, size, buf))
        goto quit;

      grub_raid_block_xor (pbuf, buf, size);

      if (grub_disk_read (array->device[q], sector, 0, size, buf))
        goto quit;

      grub_raid_block_xor (qbuf, buf, size);

      c = raid6_table2[err[1]][err[0]];
      grub_raid_block_mul (c, qbuf, size);

      c = raid6_table1[raid6_table2[err[1]][err[1]]][c];
      grub_raid_block_mul (c, pbuf, size);

      grub_raid_block_xor (pbuf, qbuf, size);
      grub_memcpy (buf, pbuf, size);
    }

quit:
  grub_free (pbuf);
  grub_free (qbuf);

  return grub_errno;
}
Exemplo n.º 27
0
Arquivo: gzio.c Projeto: TemmeR/grub2
static int
huft_build (unsigned *b,	/* code lengths in bits (all assumed <= BMAX) */
	    unsigned n,		/* number of codes (assumed <= N_MAX) */
	    unsigned s,		/* number of simple-valued codes (0..s-1) */
	    ush * d,		/* list of base values for non-simple codes */
	    ush * e,		/* list of extra bits for non-simple codes */
	    struct huft **t,	/* result: starting table */
	    int *m)		/* maximum lookup bits, returns actual */
{
  unsigned a;			/* counter for codes of length k */
  unsigned c[BMAX + 1];		/* bit length count table */
  unsigned f;			/* i repeats in table every f entries */
  int g;			/* maximum code length */
  int h;			/* table level */
  register unsigned i;		/* counter, current code */
  register unsigned j;		/* counter */
  register int k;		/* number of bits in current code */
  int l;			/* bits per table (returned in m) */
  register unsigned *p;		/* pointer into c[], b[], or v[] */
  register struct huft *q;	/* points to current table */
  struct huft r;		/* table entry for structure assignment */
  struct huft *u[BMAX];		/* table stack */
  unsigned v[N_MAX];		/* values in order of bit length */
  register int w;		/* bits before this table == (l * h) */
  unsigned x[BMAX + 1];		/* bit offsets, then code stack */
  unsigned *xp;			/* pointer into x */
  int y;			/* number of dummy codes added */
  unsigned z;			/* number of entries in current table */

  /* Generate counts for each bit length */
  grub_memset ((char *) c, 0, sizeof (c));
  p = b;
  i = n;
  do
    {
      c[*p]++;			/* assume all entries <= BMAX */
      p++;			/* Can't combine with above line (Solaris bug) */
    }
  while (--i);
  if (c[0] == n)		/* null input--all zero length codes */
    {
      *t = (struct huft *) NULL;
      *m = 0;
      return 0;
    }

  /* Find minimum and maximum length, bound *m by those */
  l = *m;
  for (j = 1; j <= BMAX; j++)
    if (c[j])
      break;
  k = j;			/* minimum code length */
  if ((unsigned) l < j)
    l = j;
  for (i = BMAX; i; i--)
    if (c[i])
      break;
  g = i;			/* maximum code length */
  if ((unsigned) l > i)
    l = i;
  *m = l;

  /* Adjust last length count to fill out codes, if needed */
  for (y = 1 << j; j < i; j++, y <<= 1)
    if ((y -= c[j]) < 0)
      return 2;			/* bad input: more codes than bits */
  if ((y -= c[i]) < 0)
    return 2;
  c[i] += y;

  /* Generate starting offsets into the value table for each length */
  x[1] = j = 0;
  p = c + 1;
  xp = x + 2;
  while (--i)
    {				/* note that i == g from above */
      *xp++ = (j += *p++);
    }

  /* Make a table of values in order of bit lengths */
  p = b;
  i = 0;
  do
    {
      if ((j = *p++) != 0)
	v[x[j]++] = i;
    }
  while (++i < n);

  /* Generate the Huffman codes and for each, make the table entries */
  x[0] = i = 0;			/* first Huffman code is zero */
  p = v;			/* grab values in bit order */
  h = -1;			/* no tables yet--level -1 */
  w = -l;			/* bits decoded == (l * h) */
  u[0] = (struct huft *) NULL;	/* just to keep compilers happy */
  q = (struct huft *) NULL;	/* ditto */
  z = 0;			/* ditto */

  /* go through the bit lengths (k already is bits in shortest code) */
  for (; k <= g; k++)
    {
      a = c[k];
      while (a--)
	{
	  /* here i is the Huffman code of length k bits for value *p */
	  /* make tables up to required level */
	  while (k > w + l)
	    {
	      h++;
	      w += l;		/* previous table always l bits */

	      /* compute minimum size table less than or equal to l bits */
	      z = (z = (unsigned) (g - w)) > (unsigned) l ? (unsigned) l : z;	/* upper limit on table size */
	      if ((f = 1 << (j = k - w)) > a + 1)	/* try a k-w bit table */
		{		/* too few codes for k-w bit table */
		  f -= a + 1;	/* deduct codes from patterns left */
		  xp = c + k;
		  while (++j < z)	/* try smaller tables up to z bits */
		    {
		      if ((f <<= 1) <= *++xp)
			break;	/* enough codes to use up j bits */
		      f -= *xp;	/* else deduct codes from patterns */
		    }
		}
	      z = 1 << j;	/* table entries for j-bit table */

	      /* allocate and link in new table */
	      q = (struct huft *) grub_malloc ((z + 1) * sizeof (struct huft));
	      if (! q)
		{
		  if (h)
		    huft_free (u[0]);
		  return 3;
		}

	      *t = q + 1;	/* link to list for huft_free() */
	      *(t = &(q->v.t)) = (struct huft *) NULL;
	      u[h] = ++q;	/* table starts after link */

	      /* connect to last table, if there is one */
	      if (h)
		{
		  x[h] = i;	/* save pattern for backing up */
		  r.b = (uch) l;	/* bits to dump before this table */
		  r.e = (uch) (16 + j);		/* bits in this table */
		  r.v.t = q;	/* pointer to this table */
		  j = i >> (w - l);	/* (get around Turbo C bug) */
		  u[h - 1][j] = r;	/* connect to last table */
		}
	    }

	  /* set up table entry in r */
	  r.b = (uch) (k - w);
	  if (p >= v + n)
	    r.e = 99;		/* out of values--invalid code */
	  else if (*p < s)
	    {
	      r.e = (uch) (*p < 256 ? 16 : 15);		/* 256 is end-of-block code */
	      r.v.n = (ush) (*p);	/* simple code is just the value */
	      p++;		/* one compiler does not like *p++ */
	    }
	  else
	    {
	      r.e = (uch) e[*p - s];	/* non-simple--look up in lists */
	      r.v.n = d[*p++ - s];
	    }

	  /* fill code-like entries with r */
	  f = 1 << (k - w);
	  for (j = i >> w; j < z; j += f)
	    q[j] = r;

	  /* backwards increment the k-bit code i */
	  for (j = 1 << (k - 1); i & j; j >>= 1)
	    i ^= j;
	  i ^= j;

	  /* backup over finished tables */
	  while ((i & ((1 << w) - 1)) != x[h])
	    {
	      h--;		/* don't need to update q */
	      w -= l;
	    }
	}
    }

  /* Return true (1) if we were given an incomplete table */
  return y != 0 && g != 1;
}
Exemplo n.º 28
0
static grub_err_t
grub_cpio_find_file (struct grub_cpio_data *data, char **name,
		     grub_uint32_t * ofs)
{
#ifndef MODE_USTAR
      struct head hd;

      if (grub_disk_read
	  (data->disk, 0, data->hofs, sizeof (hd), &hd))
	return grub_errno;

      if (hd.magic != MAGIC_BCPIO)
	return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");

      data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;

      if (hd.namesize & 1)
	hd.namesize++;

      if ((*name = grub_malloc (hd.namesize)) == NULL)
	return grub_errno;

      if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
			  hd.namesize, *name))
	{
	  grub_free (*name);
	  return grub_errno;
	}

      if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1
	  && ! grub_memcmp(*name, "TRAILER!!!", 11))
	{
	  *ofs = 0;
	  return GRUB_ERR_NONE;
	}

      data->dofs = data->hofs + sizeof (hd) + hd.namesize;
      *ofs = data->dofs + data->size;
      if (data->size & 1)
	(*ofs)++;
#else
      struct head hd;

      if (grub_disk_read
	  (data->disk, 0, data->hofs, sizeof (hd), &hd))
	return grub_errno;

      if (!hd.name[0])
	{
	  *ofs = 0;
	  return GRUB_ERR_NONE;
	}

      if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1))
	return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive");

      if ((*name = grub_strdup (hd.name)) == NULL)
	return grub_errno;

      data->size = grub_strtoul (hd.size, NULL, 8);
      data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
      *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
			   ~(GRUB_DISK_SECTOR_SIZE - 1));
#endif
  return GRUB_ERR_NONE;
}
Exemplo n.º 29
0
/* Read a line from the file FILE.  */
char *
grub_file_getline (grub_file_t file)
{
  char c;
  int pos = 0;
  int literal = 0;
  char *cmdline;
  int max_len = 64;

  /* Initially locate some space.  */
  cmdline = grub_malloc (max_len);
  if (! cmdline)
    return 0;

  while (1)
    {
      if (grub_file_read (file, &c, 1) != 1)
	break;

      /* Skip all carriage returns.  */
      if (c == '\r')
	continue;

      /* Replace tabs with spaces.  */
      if (c == '\t')
	c = ' ';

      /* The previous is a backslash, then...  */
      if (literal)
	{
	  /* If it is a newline, replace it with a space and continue.  */
	  if (c == '\n')
	    {
	      c = ' ';

	      /* Go back to overwrite the backslash.  */
	      if (pos > 0)
		pos--;
	    }

	  literal = 0;
	}

      if (c == '\\')
	literal = 1;

      if (pos == 0)
	{
	  if (! grub_isspace (c))
	    cmdline[pos++] = c;
	}
      else
	{
	  if (pos >= max_len)
	    {
	      char *old_cmdline = cmdline;
	      max_len = max_len * 2;
	      cmdline = grub_realloc (cmdline, max_len);
	      if (! cmdline)
		{
		  grub_free (old_cmdline);
		  return 0;
		}
	    }

	  if (c == '\n')
	    break;

	  cmdline[pos++] = c;
	}
    }

  cmdline[pos] = '\0';

  /* If the buffer is empty, don't return anything at all.  */
  if (pos == 0)
    {
      grub_free (cmdline);
      cmdline = 0;
    }

  return cmdline;
}
Exemplo n.º 30
0
static grub_err_t
grub_cbfs_find_file (struct grub_archelp_data *data, char **name,
		     grub_int32_t *mtime,
		     grub_uint32_t *mode)
{
  grub_size_t offset;
  for (;;
       data->dofs = data->hofs + offset,
	 data->next_hofs = ALIGN_UP (data->dofs + data->size, data->cbfs_align))
    {
      struct cbfs_file hd;
      grub_size_t namesize;

      data->hofs = data->next_hofs;

      if (data->hofs >= data->cbfs_end)
	{
	  *mode = GRUB_ARCHELP_ATTR_END;
	  return GRUB_ERR_NONE;
	}

      if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd))
	return grub_errno;

      if (grub_memcmp (hd.magic, CBFS_FILE_MAGIC, sizeof (hd.magic)) != 0)
	{
	  *mode = GRUB_ARCHELP_ATTR_END;
	  return GRUB_ERR_NONE;
	}
      data->size = grub_be_to_cpu32 (hd.len);
      (void) mtime;
      offset = grub_be_to_cpu32 (hd.offset);

      *mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME;

      namesize = offset;
      if (namesize >= sizeof (hd))
	namesize -= sizeof (hd);
      if (namesize == 0)
	continue;
      *name = grub_malloc (namesize + 1);
      if (*name == NULL)
	return grub_errno;

      if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
			  namesize, *name))
	{
	  grub_free (*name);
	  return grub_errno;
	}

      if ((*name)[0] == '\0')
	{
	  grub_free (*name);
	  *name = NULL;
	  continue;
	}

      (*name)[namesize] = 0;

      data->dofs = data->hofs + offset;
      data->next_hofs = ALIGN_UP (data->dofs + data->size, data->cbfs_align);
      return GRUB_ERR_NONE;
    }
}