Пример #1
0
grub_err_t
grub_uitree_set_prop (grub_uitree_t node, const char *name, const char *value)
{
  int ofs, len;
  grub_uiprop_t p, *ptr, next;

  ofs = grub_strlen (name) + 1;
  len = ofs + grub_strlen (value) + 1;

  next = 0;
  ptr = &node->prop;
  while (*ptr)
    {
      if (! grub_strcmp ((*ptr)->name, name))
	{
	  next = (*ptr)->next;
	  break;
	}
      ptr = &((*ptr)->next);
    }

  p = grub_realloc (*ptr, sizeof (struct grub_uiprop) + len);
  if (! p)
    return grub_errno;

  *ptr = p;
  p->next = next;
  grub_strcpy (p->name, name);
  grub_strcpy (p->name + ofs, value);
  p->value = &p->name[ofs];

  return grub_errno;
}
Пример #2
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,
		  enum grub_file_type type)
{
  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);
    }

  file = grub_file_open (filename, type);

  grub_free (buf);
  return file;
}
Пример #3
0
static int
grub_xnu_scan_dir_for_kexts_hook (const char *filename,
				  const struct grub_dirhook_info *info,
				  void *closure)
{
  struct grub_xnu_scan_dir_for_kexts_closure *c = closure;
  char *newdirname;
  if (! info->dir)
    return 0;
  if (filename[0] == '.')
    return 0;

  if (grub_strlen (filename) < 5 ||
      grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0)
    return 0;

  newdirname
    = grub_malloc (grub_strlen (c->dirname) + grub_strlen (filename) + 2);

  /* It's a .kext. Try to load it. */
  if (newdirname)
    {
      grub_strcpy (newdirname, c->dirname);
      newdirname[grub_strlen (newdirname) + 1] = 0;
      newdirname[grub_strlen (newdirname)] = '/';
      grub_strcpy (newdirname + grub_strlen (newdirname), filename);
      grub_xnu_load_kext_from_dir (newdirname, c->osbundlerequired,
				   c->maxrecursion);
      if (grub_errno == GRUB_ERR_BAD_OS)
	grub_errno = GRUB_ERR_NONE;
      grub_free (newdirname);
    }
  return 0;
}
Пример #4
0
static char *
make_dir (const char *prefix, const char *start, const char *end)
{
  char ch;
  unsigned i;
  unsigned n;
  char *result;

  i = grub_strlen (prefix);
  n = i + end - start;

  result = grub_malloc (n + 1);
  if (! result)
    return 0;

  grub_strcpy (result, prefix);
  while (start < end && (ch = *start++))
    if (ch == '\\' && isregexop (*start))
      result[i++] = *start++;
    else
      result[i++] = ch;

  result[i] = '\0';
  return result;
}
Пример #5
0
static int
grub_xnu_load_kext_from_dir_hook (const char *filename,
				  const struct grub_dirhook_info *info,
				  void *closure)
{
  struct grub_xnu_load_kext_from_dir_closure *c = closure;

  if (grub_strlen (filename) > 15)
    return 0;
  grub_strcpy (c->newdirname + grub_strlen (c->dirname) + 1, filename);

  /* If the kext contains directory "Contents" all real stuff is in
     this directory. */
  if (info->dir && grub_strcasecmp (filename, "Contents") == 0)
    grub_xnu_load_kext_from_dir (c->newdirname, c->osbundlerequired,
				 c->maxrecursion - 1);

  /* Directory "Plugins" contains nested kexts. */
  if (info->dir && grub_strcasecmp (filename, "Plugins") == 0)
    grub_xnu_scan_dir_for_kexts (c->newdirname, c->osbundlerequired,
				 c->maxrecursion - 1);

  /* Directory "MacOS" contains executable, otherwise executable is
     on the top. */
  if (info->dir && grub_strcasecmp (filename, "MacOS") == 0)
    c->usemacos = 1;

  /* Info.plist is the file which governs our future actions. */
  if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0
      && ! c->plistname)
    c->plistname = grub_strdup (c->newdirname);
  return 0;
}
Пример #6
0
static char *
make_install_device (void)
{
  /* XXX: This should be enough.  */
  char dev[100], *ptr = dev;

  if (grub_prefix[0] != '(')
    {
      /* No hardcoded root partition - make it from the boot drive and the
	 partition number encoded at the install time.  */
      if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL)
	{
	  grub_strcpy (dev, "(pxe");
	  ptr += sizeof ("(pxe") - 1;
	}
      else
	{
	  grub_snprintf (dev, sizeof (dev),
			 "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
			 grub_boot_drive & 0x7f);
	  ptr += grub_strlen (ptr);

	  if (grub_install_dos_part >= 0)
	    grub_snprintf (ptr, sizeof (dev) - (ptr - dev),
			   ",%u", grub_install_dos_part + 1);
	  ptr += grub_strlen (ptr);

	  if (grub_install_bsd_part >= 0)
	    grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%u",
			   grub_install_bsd_part + 1);
	  ptr += grub_strlen (ptr);
	}

      grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix);
      grub_strcpy (grub_prefix, dev);
    }
  else if (grub_prefix[1] == ',' || grub_prefix[1] == ')')
    {
      /* We have a prefix, but still need to fill in the boot drive.  */
      grub_snprintf (dev, sizeof (dev),
		     "(%cd%u%s", (grub_boot_drive & 0x80) ? 'h' : 'f',
		     grub_boot_drive & 0x7f, grub_prefix + 1);
      grub_strcpy (grub_prefix, dev);
    }

  return grub_prefix;
}
Пример #7
0
static int
grub_ofdisk_iterate (int (*hook) (const char *name),
		     grub_disk_pull_t pull)
{
  unsigned i;

  if (pull != GRUB_DISK_PULL_NONE)
    return 0;

  scan ();
  
  for (i = 0; i < ARRAY_SIZE (ofdisk_hash); i++)
    {
      static struct ofdisk_hash_ent *ent;
      for (ent = ofdisk_hash[i]; ent; ent = ent->next)
	{
	  if (!ent->shortest)
	    continue;
	  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
	    {
	      grub_ieee1275_phandle_t dev;
	      char tmp[8];

	      if (grub_ieee1275_finddevice (ent->devpath, &dev))
		{
		  grub_dprintf ("disk", "finddevice (%s) failed\n",
				ent->devpath);
		  continue;
		}

	      if (grub_ieee1275_get_property (dev, "iconname", tmp,
					      sizeof tmp, 0))
		{
		  grub_dprintf ("disk", "get iconname failed\n");
		  continue;
		}

	      if (grub_strcmp (tmp, "sdmmc") != 0)
		{
		  grub_dprintf ("disk", "device is not an SD card\n");
		  continue;
		}
	    }

	  if (grub_strncmp (ent->shortest, "cdrom", 5) == 0)
	    continue;

	  {
	    char buffer[sizeof ("ieee1275/") + grub_strlen (ent->shortest)];
	    char *ptr;
	    ptr = grub_stpcpy (buffer, "ieee1275/");
	    grub_strcpy (ptr, ent->shortest);
	    if (hook (buffer))
	      return 1;
	  }
	}
    }	  
  return 0;
}
Пример #8
0
/* Add CMDLINE to the history buffer.  */
static void
add_history (const char *cmdline, int no)
{
  grub_memmove ((char *) HISTORY_BUF + MAX_CMDLINE * (no + 1),
		(char *) HISTORY_BUF + MAX_CMDLINE * no,
		MAX_CMDLINE * (num_history - no));
  grub_strcpy ((char *) HISTORY_BUF + MAX_CMDLINE * no, cmdline);
  if (num_history < HISTORY_SIZE)
    num_history++;
}
Пример #9
0
grub_uitree_t
grub_uitree_create_node (const char *name)
{
  grub_uitree_t n;

  n = grub_zalloc (sizeof (struct grub_uitree) + grub_strlen (name) + 1);
  if (! n)
    return 0;

  grub_strcpy (n->name, name);
  return n;
}
Пример #10
0
static void
insert_item (grub_autolist_t *list, char *name, char *file)
{
  grub_autolist_t p;

  p = grub_malloc (sizeof (*p));
  if (! p)
    return;

  p->name = grub_malloc (grub_strlen (name) + grub_strlen (file) + 2);
  if (! p->name)
    {
      grub_free (p);
      return;
    }

  grub_strcpy (p->name, name);
  p->value = p->name + grub_strlen (name) + 1;
  grub_strcpy (p->value, file);
  grub_list_push (GRUB_AS_LIST_P (list), GRUB_AS_LIST (p));
}
Пример #11
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;
}
Пример #12
0
int
set_variable(const char *name, const char *value)
{
	unsigned int i;
	unsigned int avail = nexpvars;

	if (strlen(name) >= sizeof (expvars[0].v_name))
		return (ERR_WONT_FIT);

	if (value != NULL && strlen(value) >= sizeof (expvars[0].v_value))
		return (ERR_WONT_FIT);

	for (i = 0; i < nexpvars; i++) {
		if (expvars[i].v_flags & EVF_DEFINED) {
			if (grub_strcmp(expvars[i].v_name, name) == 0)
				break;
		} else if (i < avail) {
			avail = i;
		}
	}

	if (i == nexpvars) {
		if (avail == nexpvars)
			return (ERR_WONT_FIT);

		i = avail;
		(void) grub_strcpy(expvars[i].v_name, name);
		expvars[i].v_flags = EVF_DEFINED;
	}

	if (value != NULL) {
		(void) grub_strcpy(expvars[i].v_value, value);
		expvars[i].v_flags |= EVF_VALUESET;
	} else {
		expvars[i].v_flags &= ~EVF_VALUESET;
	}

	return (0);
}
Пример #13
0
static grub_err_t
grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
		  grub_size_t size, char *buf)
{
  grub_ssize_t status, actual;
  unsigned long long pos;

  if (disk->data != last_devpath)
    {
      if (last_ihandle)
	grub_ieee1275_close (last_ihandle);
      last_ihandle = 0;
      last_devpath = NULL;

      if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
	{
	  char name2[grub_strlen (disk->data) + 3];
	  char *p;
	  
	  grub_strcpy (name2, disk->data);
	  p = name2 + grub_strlen (name2);
	  *p++ = ':';
	  *p++ = '0';
	  *p = 0;
	  grub_ieee1275_open (name2, &last_ihandle);
	}
      else
	grub_ieee1275_open (disk->data, &last_ihandle);
      if (! last_ihandle)
	return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
      last_devpath = disk->data;      
    }

  pos = sector * 512UL;

  grub_ieee1275_seek (last_ihandle, pos, &status);
  if (status < 0)
    return grub_error (GRUB_ERR_READ_ERROR,
		       "seek error, can't seek block %llu",
		       (long long) sector);
  grub_ieee1275_read (last_ihandle, buf, size * 512UL, &actual);
  if (actual != (grub_ssize_t) (size * 512UL))
    return grub_error (GRUB_ERR_READ_ERROR, "read error on block: %llu",
		       (long long) sector);

  return 0;
}
Пример #14
0
static int add_subnode (void *fdt, int parentoffset, const char *name)
{
  grub_uint32_t *token = (void *) ((grub_addr_t) fdt
                                   + grub_fdt_get_off_dt_struct(fdt)
                                   + parentoffset);
  grub_uint32_t *end = (void *) struct_end (fdt);
  unsigned int entry_size = node_entry_size (name);
  unsigned int struct_size = grub_fdt_get_size_dt_struct(fdt);
  char *node_name;

  SKIP_NODE_NAME(node_name, token, end);

  /* Insert the new subnode just after the properties of the parent node (if
     any).*/
  while (1)
  {
    if (token >= end)
      return -1;
    switch (grub_be_to_cpu32(*token))
    {
      case FDT_PROP:
        /* Skip len, nameoff and property value. */
        token += prop_entry_size(grub_be_to_cpu32(*(token + 1)))
                 / sizeof(*token);
        break;
      case FDT_BEGIN_NODE:
      case FDT_END_NODE:
        goto insert;
      case FDT_NOP:
        token++;
        break;
      default:
        /* invalid token */
        return -1;
    }
  }
insert:
  grub_memmove (token + entry_size / sizeof(*token), token,
                (grub_addr_t) end - (grub_addr_t) token);
  *token = grub_cpu_to_be32_compile_time(FDT_BEGIN_NODE);
  token[entry_size / sizeof(*token) - 2] = 0;	/* padding bytes */
  grub_strcpy((char *) (token + 1), name);
  token[entry_size / sizeof(*token) - 1] = grub_cpu_to_be32_compile_time(FDT_END_NODE);
  grub_fdt_set_size_dt_struct (fdt, struct_size + entry_size);
  return ((grub_addr_t) token - (grub_addr_t) fdt
          - grub_fdt_get_off_dt_struct(fdt));
}
Пример #15
0
static grub_err_t
grub_mb2_tag_name_create (void)
{
  struct multiboot_tag_name *name;
  grub_addr_t name_addr;
  grub_err_t err;
  const char *grub_version = PACKAGE_STRING;

  err = grub_mb2_tag_alloc (&name_addr, MULTIBOOT2_TAG_NAME,
			   sizeof (struct multiboot_tag_name) +
			   sizeof (grub_version) + 1);
  if (err)
    return err;

  name = (struct multiboot_tag_name *) name_addr;
  grub_strcpy (name->name, grub_version);

  return GRUB_ERR_NONE;
}
Пример #16
0
void
grub_machine_set_prefix (void)
{
  if (grub_prefix[0] != '(')
    {
      char bootpath[IEEE1275_MAX_PATH_LEN];
      char *prefix, *path, *colon;
      grub_ssize_t actual;

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

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

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

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

      grub_strcpy (grub_prefix, path);

      grub_free (path);
      grub_free (prefix);
    }

  grub_env_set ("prefix", grub_prefix);
}
Пример #17
0
static grub_err_t
grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector)
{
  grub_ssize_t status;
  unsigned long long pos;

  if (disk->data != last_devpath)
    {
      if (last_ihandle)
	grub_ieee1275_close (last_ihandle);
      last_ihandle = 0;
      last_devpath = NULL;

      if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
	{
	  char name2[grub_strlen (disk->data) + 3];
	  char *p;
	  
	  grub_strcpy (name2, disk->data);
	  p = name2 + grub_strlen (name2);
	  *p++ = ':';
	  *p++ = '0';
	  *p = 0;
	  grub_ieee1275_open (name2, &last_ihandle);
	}
      else
	grub_ieee1275_open (disk->data, &last_ihandle);
      if (! last_ihandle)
	return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
      last_devpath = disk->data;      
    }

  pos = sector << GRUB_DISK_SECTOR_BITS;

  grub_ieee1275_seek (last_ihandle, pos, &status);
  if (status < 0)
    return grub_error (GRUB_ERR_READ_ERROR,
		       "seek error, can't seek block %llu",
		       (long long) sector);
  return 0;
}
Пример #18
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;
  int l;

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

  grub_strcpy (path, dir);
  l = grub_strlen (path);
  if (path[l-1] != '/')
    {
      path[l] = '/';
      path[l+1] = 0;
    }
  grub_strcat (path, class_name);
  grub_strcat (path, icon_extension);

  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;
}
Пример #19
0
/* Create the tag containing the cmdline and the address of the module data.  */
static grub_err_t
grub_mb2_tag_module_create (grub_addr_t modaddr, grub_size_t modsize,
			    char *type, int key, int argc, char *argv[])
{
  struct multiboot_tag_module *module;
  grub_ssize_t argslen = 0;
  grub_err_t err;
  char *p;
  grub_addr_t module_addr;
  int i;

  /* Allocate enough space for the arguments and spaces between them.  */
  for (i = 0; i < argc; i++)
    argslen += grub_strlen (argv[i]) + 1;

  /* Note: includes implicit 1-byte cmdline.  */
  err = grub_mb2_tag_alloc (&module_addr, key,
			   sizeof (struct multiboot_tag_module) + argslen);
  if (err)
    return grub_errno;

  module = (struct multiboot_tag_module *) module_addr;
  module->addr = modaddr;
  module->size = modsize;
  grub_strcpy(module->type, type);

  /* Fill in the command line.  */
  p = module->cmdline;
  for (i = 0; i < argc; i++)
    {
      p = grub_stpcpy (p, argv[i]);
      *p++ = ' ';
    }
  module->cmdline[argslen] = '\0';

  return GRUB_ERR_NONE;
}
Пример #20
0
int process_cfg(char *cfg)
{
  // buffer for config file reading
  static char s[BUFSIZE];
  static int  s_pos = 0;
  // second buffer
  static char str[BUFSIZE];
  static int  str_pos = 0;
  char *p, *line, *q;
  char f, g;
  unsigned int size, sz;
  unsigned int rd;
  int bytes_read = 0;
  int i;

  if (u_open(cfg, &size)) {
    printf("Cannot open config file!\r\n");
    return 0;
  }

  u_close();

  //grub_memset(s, 0, sizeof(s));

  sz = size;
  while (sz)
  {
    // read new buffer
    if (u_open(cfg, &size)) {
      printf("Cannot open config file!\r\n");
      return 0;
    }

    u_seek(bytes_read);

    rd = u_read(buf, sizeof(buf));
    if (!rd)
    {
      printf("process_cfg(): read returned zero bytes\r\n");
      return 0;
    }

    sz -= rd;
    bytes_read += rd;

    u_close();

    if (sz && !rd)
    {
      printf("Can't read from config file!\r\n");
      return 0;
    }

    f = 1;
    p = buf;
    while (*p && f)
    {
      // read new line from current buffer
      line = getline(&p, rd);
      i = grub_strlen(line);
      if (s_pos + i > BUFSIZE)
        panic("string s too long to fit in buffer!\r\n", cfg);
      grub_strcpy(s + s_pos, line);
      s_pos += i;
      f = (p - buf < rd);
      g = f || (!f && (buf[rd - 1] == '\n'));
      if (g)
      {
        // delete CR and LF symbols at the end
        line = strip(trim(s));
        // skip comments ";"
        i = grub_index(';', line);
        if (i) line[i - 1] = '\0';
        // skip comments "#"
        i = grub_index('#', line);
        if (i) line[i - 1] = '\0';
        // delete leading and trailing spaces
        line = strip(line);

        // line continuation symbol ('^' or '&') support
        i = grub_strlen(line);
        if (line[i - 1] == '^' || line[i - 1] == '&')
        {
          // the current line continued
          line[i - 1] = '\0';
          if (str_pos + i - 1 > BUFSIZE)
            panic("string str too long to fit in buffer!\r\n", cfg);
          grub_strcpy(str + str_pos, line);
          str_pos += i - 1;
          s[0] = '\0';
          s_pos = 0;

          continue;
        }
        else
        {
          // the line ends
          if (str_pos + i > BUFSIZE)
            panic("string str too long to fit in buffer!\r\n", cfg);
          grub_strcpy(str + str_pos, line);
          str_pos = 0;
          s[0] = '\0';
          s_pos = 0;
        }

        // expand variables
        //expand_vars(s, str);

        // process the line
        if (!process_cfg_line(str))
          return -1;
      }
    }
  }

  return 1;
}
Пример #21
0
static char *
grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
{
  char type[64]; /* XXX check size.  */
  char *device = grub_ieee1275_get_devname (path);
  char *args = grub_ieee1275_get_devargs (path);
  char *ret = 0;
  grub_ieee1275_phandle_t dev;

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

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

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

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

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

fail:
  grub_free (device);
  grub_free (args);
  return ret;
}
Пример #22
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;
}
Пример #23
0
static grub_err_t
tftp_open (struct grub_file *file, const char *filename)
{
    struct tftphdr *tftph;
    char *rrq;
    int i;
    int rrqlen;
    int hdrlen;
    grub_uint8_t open_data[1500];
    struct grub_net_buff nb;
    tftp_data_t data;
    grub_err_t err;
    grub_uint8_t *nbd;
    grub_net_network_level_address_t addr;

    data = grub_zalloc (sizeof (*data));
    if (!data)
        return grub_errno;

    nb.head = open_data;
    nb.end = open_data + sizeof (open_data);
    grub_netbuff_clear (&nb);

    grub_netbuff_reserve (&nb, 1500);
    err = grub_netbuff_push (&nb, sizeof (*tftph));
    if (err)
        return err;

    tftph = (struct tftphdr *) nb.data;

    rrq = (char *) tftph->u.rrq;
    rrqlen = 0;

    tftph->opcode = grub_cpu_to_be16_compile_time (TFTP_RRQ);
    grub_strcpy (rrq, filename);
    rrqlen += grub_strlen (filename) + 1;
    rrq += grub_strlen (filename) + 1;

    grub_strcpy (rrq, "octet");
    rrqlen += grub_strlen ("octet") + 1;
    rrq += grub_strlen ("octet") + 1;

    grub_strcpy (rrq, "blksize");
    rrqlen += grub_strlen ("blksize") + 1;
    rrq += grub_strlen ("blksize") + 1;

    grub_strcpy (rrq, "1024");
    rrqlen += grub_strlen ("1024") + 1;
    rrq += grub_strlen ("1024") + 1;

    grub_strcpy (rrq, "tsize");
    rrqlen += grub_strlen ("tsize") + 1;
    rrq += grub_strlen ("tsize") + 1;

    grub_strcpy (rrq, "0");
    rrqlen += grub_strlen ("0") + 1;
    rrq += grub_strlen ("0") + 1;
    hdrlen = sizeof (tftph->opcode) + rrqlen;

    err = grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen));
    if (err)
        return err;

    file->not_easily_seekable = 1;
    file->data = data;

    data->pq = grub_priority_queue_new (sizeof (struct grub_net_buff *), cmp);
    if (!data->pq)
        return grub_errno;

    err = grub_net_resolve_address (file->device->net->server, &addr);
    if (err)
    {
        destroy_pq (data);
        return err;
    }

    data->sock = grub_net_udp_open (addr,
                                    TFTP_SERVER_PORT, tftp_receive,
                                    file);
    if (!data->sock)
    {
        destroy_pq (data);
        return grub_errno;
    }

    /* Receive OACK packet.  */
    nbd = nb.data;
    for (i = 0; i < GRUB_NET_TRIES; i++)
    {
        nb.data = nbd;
        err = grub_net_send_udp_packet (data->sock, &nb);
        if (err)
        {
            grub_net_udp_close (data->sock);
            destroy_pq (data);
            return err;
        }
        grub_net_poll_cards (GRUB_NET_INTERVAL + (i * GRUB_NET_INTERVAL_ADDITION),
                             &data->have_oack);
        if (data->have_oack)
            break;
    }

    if (!data->have_oack)
        grub_error (GRUB_ERR_TIMEOUT, N_("time out opening `%s'"), filename);
    else
        grub_error_load (&data->save_err);
    if (grub_errno)
    {
        grub_net_udp_close (data->sock);
        destroy_pq (data);
        return grub_errno;
    }

    file->size = data->file_size;

    return GRUB_ERR_NONE;
}
Пример #24
0
static grub_err_t
interactive (void)
{
  const char *ps1 = "lua> ";
  const char *ps2 = "lua>> ";
  const char *prompt = ps1;
  char *line;
  char *chunk = NULL;
  size_t len;
  size_t oldlen = 0;
  int r;

  grub_printf ("%s", N_ ("Welcome to lua, press the escape key to exit."));

  while ((line = grub_cmdline_get (prompt)) != NULL)
    {
      /* len = lenght of chunk + line + newline character */
      len = oldlen + grub_strlen (line) + 1;
      chunk = grub_realloc (chunk, len + 1);
      grub_strcpy (chunk + oldlen , line);
      chunk[len - 1] = '\n';
      chunk[len] = '\0';
      grub_free (line);

      r = luaL_loadbuffer (state, chunk, len, "stdin");
      if (!r)
	{
	  /* No error: Execute this chunk and prepare to read another */
	  r = lua_pcall (state, 0, 0, 0);
	  if (r)
	    {
	      handle_lua_error ("Lua");
	      grub_print_error ();
	    }

	  grub_free (chunk);
	  chunk = NULL;
	  len = 0;
	  prompt = ps1;
	}
      else if (incomplete (state, r))
	{
	  /* Chunk is incomplete, try reading another line */
	  prompt = ps2;
	}
      else if (r == LUA_ERRSYNTAX)
	{
	  handle_lua_error ("Lua");
	  grub_print_error ();

	  /* This chunk is garbage, try starting another one */
	  grub_free (chunk);
	  chunk = NULL;
	  len = 0;
	  prompt = ps1;
	}
      else
	{
	  /* Handle errors other than syntax errors (out of memory, etc.) */
	  grub_free (chunk);
	  handle_lua_error ("Lua parser failed");
	  return grub_errno;
	}

      oldlen = len;
    }

  grub_free (chunk);
  lua_gc (state, LUA_GCCOLLECT, 0);

  return grub_errno;
}
Пример #25
0
static grub_uitree_t
grub_uitree_load_buf (const char *prefix, int prefix_len, grub_uitree_t root,
		      char *buf, int size, int flags)
{
  int type, count, sub;
  char pre;
  grub_uitree_t node;

  if (((grub_uint8_t) buf[0] == 0xef) &&
      ((grub_uint8_t) buf[1] == 0xbb) &&
      ((grub_uint8_t) buf[2] == 0xbf))
    {
      buf += 3;
      size -= 3;
    }

  node = root;
  pre = 0;
  while ((type = read_token (buf, &pre, size, &count, &sub))
	 != TOKEN_TYPE_ERROR)
    {
      if (type == TOKEN_TYPE_STRING)
	{
	  char *str, *str2;

	  str = buf;
	  buf += count;
	  size -= count;
	  type = read_token (buf, &pre, size, &count, &sub);
	  str2 = buf;
	  buf += count;
	  size -= count;
	  if (type == TOKEN_TYPE_EQUAL)
	    {
	      char *p;

	      if (read_token (buf, &pre, size, &count, &sub)
		  != TOKEN_TYPE_STRING)
		break;

	      if (sub)
		{
		  char *p1, *p2;
		  
		  p = grub_malloc (grub_strlen (buf) + (prefix_len - 2) * sub
				   + 1);
		  if (! p)
		    break;

		  p1 = buf;
		  p2 = p;
		  while (1)
		    {
		      char *t;

		      t = grub_strstr (p1, "$$");
		      if (t)
			{
			  grub_memcpy (p2, p1, t - p1);
			  p2 += (t - p1);
			  grub_memcpy (p2, prefix, prefix_len);
			  p2 += prefix_len;
			  p1 = t + 2;
			}
		      else
			{
			  grub_strcpy (p2, p1);
			  break;
			}
		    }
		}
	      else
		p = buf;		
		
	      if (grub_uitree_set_prop (node, str, p))
		break;

	      if (sub)
		grub_free (p);

	      buf += count;
	      size -= count;
	    }
	  else if (type == TOKEN_TYPE_LBRACKET)
	    {
	      grub_uitree_t p;
	      int method;

	      if ((flags & GRUB_UITREE_LOAD_FLAG_ROOT) && (node == root))
		method = METHOD_REPLACE;
	      else
		method = METHOD_APPEND;

	      if (*str == '+')
		{
		  method = METHOD_MERGE;
		  str++;
		}
	      else if (*str == '-')
		{
		  method = METHOD_REPLACE;
		  str++;
		}

	      if (! *str)
		break;

	      if (flags & GRUB_UITREE_LOAD_FLAG_SINGLE)
		method = METHOD_APPEND;

	      p = (method == METHOD_APPEND) ? 0 : grub_uitree_find (node, str);
	      if (p)
		{
		  if (method == METHOD_REPLACE)
		    grub_uitree_reset_node (p);
		  node = p;
		}
	      else
		{
		  grub_uitree_t n;

		  n = grub_uitree_create_node (str);
		  if (! n)
		    break;

		  grub_tree_add_child (GRUB_AS_TREE (node), GRUB_AS_TREE (n),
				       -1);
		  node = n;
		}
	    }
	  else if ((type == TOKEN_TYPE_STRING) &&
		   ((! grub_strcmp (str, "include")) ||
		    (! grub_strcmp (str, "-include"))))
	    {
	      int ignore_error;
	      grub_uitree_t n;
	      int b;
	      int pos;
	      char *p;

	      ignore_error = (str[0] == '-');
	      pos = prefix_len;
	      while  ((str2[0] == '.') && (str2[1] == '.'))
		{
		  str2 += 2;
		  if (*str2 == '/')
		    str2++;

		  while ((pos > 0) && (prefix[pos - 1] != '/'))
		    pos--;
		  if (pos > 0)
		    pos--;
		}
		
	      p = grub_malloc (pos + grub_strlen (str2) + 2);
	      if (! p)
		break;

	      grub_memcpy (p, prefix, pos);
	      p[pos++] = '/';
	      grub_strcpy (p + pos, str2);

	      b = (node == root) ? flags : 0;
	      n = grub_uitree_load_file (node, p, b);
	      grub_free (p);
	      if (ignore_error)
		grub_errno = 0;
	      else if (grub_errno)
		break;

	      if ((b & GRUB_UITREE_LOAD_FLAG_SINGLE) && (n != NULL))
		return n;
	    }
	  else
	    break;
	}
      else if (type == TOKEN_TYPE_RBRACKET)
	{
	  buf += count;
	  size -= count;
	  if (node == root)
	    break;

	  if ((flags & GRUB_UITREE_LOAD_FLAG_SINGLE) && (node->parent == root))
	    return node;

	  node = node->parent;
	}
      else
	break;
    }

  return 0;
}
Пример #26
0
char *
grub_legacy_parse (const char *buf, char **entryname, char **suffix)
{
  const char *ptr;
  const char *cmdname;
  unsigned i, cmdnum;
  char *args[ARRAY_SIZE (legacy_commands[0].argt)];

  *suffix = NULL;

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

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

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

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

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

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

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

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

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

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

      outptr = outbuf;

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

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

      grub_strcpy (outptr, "\n");

      return grub_strdup (outbuf);
    }

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

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

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

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

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

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

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

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

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

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

  {
    char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1],
				args[2], args[3]);
    grub_free (args[0]);
    grub_free (args[1]);
    grub_free (args[2]);
    grub_free (args[3]);
    return ret;
  }
}
Пример #27
0
int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name,
		       const void *val, grub_uint32_t len)
{
  grub_uint32_t *prop;
  int prop_name_present = 0;
  grub_uint32_t nameoff = 0;

  if ((nodeoffset >= grub_fdt_get_size_dt_struct (fdt)) || (nodeoffset & 0x3)
      || (grub_be_to_cpu32(*(grub_uint32_t *) ((grub_addr_t) fdt
                           + grub_fdt_get_off_dt_struct (fdt) + nodeoffset))
          != FDT_BEGIN_NODE))
    return -1;
  prop = find_prop (fdt, nodeoffset, name);
  if (prop)
    {
	  grub_uint32_t prop_len = ALIGN_UP(grub_be_to_cpu32 (*(prop + 1)),
                                        sizeof(grub_uint32_t));
	  grub_uint32_t i;

      prop_name_present = 1;
	  for (i = 0; i < prop_len / sizeof(grub_uint32_t); i++)
        *(prop + 3 + i) = grub_cpu_to_be32_compile_time (FDT_NOP);
      if (len > ALIGN_UP(prop_len, sizeof(grub_uint32_t)))
        {
          /* Length of new property value is greater than the space allocated
             for the current value: a new entry needs to be created, so save the
             nameoff field of the current entry and replace the current entry
             with NOP tokens. */
          nameoff = grub_be_to_cpu32 (*(prop + 2));
          *prop = *(prop + 1) = *(prop + 2) = grub_cpu_to_be32_compile_time (FDT_NOP);
          prop = NULL;
        }
    }
  if (!prop || !prop_name_present) {
    unsigned int needed_space = 0;

    if (!prop)
      needed_space = prop_entry_size(len);
    if (!prop_name_present)
      needed_space += grub_strlen (name) + 1;
    if (needed_space > get_free_space (fdt))
      return -1;
    if (rearrange_blocks (fdt, !prop ? prop_entry_size(len) : 0) < 0)
      return -1;
  }
  if (!prop_name_present) {
    /* Append the property name at the end of the strings block. */
    nameoff = grub_fdt_get_size_dt_strings (fdt);
    grub_strcpy ((char *) fdt + grub_fdt_get_off_dt_strings (fdt) + nameoff,
                 name);
    grub_fdt_set_size_dt_strings (fdt, grub_fdt_get_size_dt_strings (fdt)
                                  + grub_strlen (name) + 1);
  }
  if (!prop) {
    char *node_name = (char *) ((grub_addr_t) fdt
                                + grub_fdt_get_off_dt_struct (fdt) + nodeoffset
                                + sizeof(grub_uint32_t));

    prop = (void *) (node_name + ALIGN_UP(grub_strlen(node_name) + 1, 4));
    grub_memmove (prop + prop_entry_size(len) / sizeof(*prop), prop,
                  struct_end(fdt) - (grub_addr_t) prop);
    grub_fdt_set_size_dt_struct (fdt, grub_fdt_get_size_dt_struct (fdt)
                                 + prop_entry_size(len));
    *prop = grub_cpu_to_be32_compile_time (FDT_PROP);
    *(prop + 2) = grub_cpu_to_be32 (nameoff);
  }
  *(prop + 1) = grub_cpu_to_be32 (len);

  /* Insert padding bytes at the end of the value; if they are not needed, they
     will be overwritten by the following memcpy. */
  *(prop + prop_entry_size(len) / sizeof(grub_uint32_t) - 1) = 0;

  grub_memcpy (prop + 3, val, len);
  return 0;
}
Пример #28
0
static int
grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
			  grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
  struct grub_iso9660_dir dirent;
  grub_off_t offset = 0;
  grub_off_t len;
  struct iterate_dir_ctx ctx;

  len = get_node_size (dir);

  for (; offset < len; offset += dirent.len)
    {
      ctx.symlink = 0;
      ctx.was_continue = 0;

      if (read_node (dir, offset, sizeof (dirent), (char *) &dirent))
	return 0;

      /* The end of the block, skip to the next one.  */
      if (!dirent.len)
	{
	  offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ;
	  continue;
	}

      {
	char name[MAX_NAMELEN + 1];
	int nameoffset = offset + sizeof (dirent);
	struct grub_fshelp_node *node;
	int sua_off = (sizeof (dirent) + dirent.namelen + 1
		       - (dirent.namelen % 2));
	int sua_size = dirent.len - sua_off;

	sua_off += offset + dir->data->susp_skip;

	ctx.filename = 0;
	ctx.filename_alloc = 0;
	ctx.type = GRUB_FSHELP_UNKNOWN;

	if (dir->data->rockridge
	    && grub_iso9660_susp_iterate (dir, sua_off, sua_size,
					  susp_iterate_dir, &ctx))
	  return 0;

	/* Read the name.  */
	if (read_node (dir, nameoffset, dirent.namelen, (char *) name))
	  return 0;

	node = grub_malloc (sizeof (struct grub_fshelp_node));
	if (!node)
	  return 0;

	node->alloc_dirents = ARRAY_SIZE (node->dirents);
	node->have_dirents = 1;

	/* Setup a new node.  */
	node->data = dir->data;
	node->have_symlink = 0;

	/* If the filetype was not stored using rockridge, use
	   whatever is stored in the iso9660 filesystem.  */
	if (ctx.type == GRUB_FSHELP_UNKNOWN)
	  {
	    if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR)
	      ctx.type = GRUB_FSHELP_DIR;
	    else
	      ctx.type = GRUB_FSHELP_REG;
	  }

	/* . and .. */
	if (!ctx.filename && dirent.namelen == 1 && name[0] == 0)
	  ctx.filename = (char *) ".";

	if (!ctx.filename && dirent.namelen == 1 && name[0] == 1)
	  ctx.filename = (char *) "..";

	/* The filename was not stored in a rock ridge entry.  Read it
	   from the iso9660 filesystem.  */
	if (!dir->data->joliet && !ctx.filename)
	  {
	    char *ptr;
	    name[dirent.namelen] = '\0';
	    ctx.filename = grub_strrchr (name, ';');
	    if (ctx.filename)
	      *ctx.filename = '\0';
	    /* ISO9660 names are not case-preserving.  */
	    ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE;
	    for (ptr = name; *ptr; ptr++)
	      *ptr = grub_tolower (*ptr);
	    if (ptr != name && *(ptr - 1) == '.')
	      *(ptr - 1) = 0;
	    ctx.filename = name;
	  }

        if (dir->data->joliet && !ctx.filename)
          {
            char *semicolon;

            ctx.filename = grub_iso9660_convert_string
                  ((grub_uint8_t *) name, dirent.namelen >> 1);

	    semicolon = grub_strrchr (ctx.filename, ';');
	    if (semicolon)
	      *semicolon = '\0';

            ctx.filename_alloc = 1;
          }

	node->dirents[0] = dirent;
	while (dirent.flags & FLAG_MORE_EXTENTS)
	  {
	    offset += dirent.len;
	    if (read_node (dir, offset, sizeof (dirent), (char *) &dirent))
	      {
		if (ctx.filename_alloc)
		  grub_free (ctx.filename);
		grub_free (node);
		return 0;
	      }
	    if (node->have_dirents >= node->alloc_dirents)
	      {
		struct grub_fshelp_node *new_node;
		node->alloc_dirents *= 2;
		new_node = grub_realloc (node, 
					 sizeof (struct grub_fshelp_node)
					 + ((node->alloc_dirents
					     - ARRAY_SIZE (node->dirents))
					    * sizeof (node->dirents[0])));
		if (!new_node)
		  {
		    if (ctx.filename_alloc)
		      grub_free (ctx.filename);
		    grub_free (node);
		    return 0;
		  }
		node = new_node;
	      }
	    node->dirents[node->have_dirents++] = dirent;
	  }
	if (ctx.symlink)
	  {
	    if ((node->alloc_dirents - node->have_dirents)
		* sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1)
	      {
		struct grub_fshelp_node *new_node;
		new_node = grub_realloc (node,
					 sizeof (struct grub_fshelp_node)
					 + ((node->alloc_dirents
					     - ARRAY_SIZE (node->dirents))
					    * sizeof (node->dirents[0]))
					 + grub_strlen (ctx.symlink) + 1);
		if (!new_node)
		  {
		    if (ctx.filename_alloc)
		      grub_free (ctx.filename);
		    grub_free (node);
		    return 0;
		  }
		node = new_node;
	      }
	    node->have_symlink = 1;
	    grub_strcpy (node->symlink
			 + node->have_dirents * sizeof (node->dirents[0])
			 - sizeof (node->dirents), ctx.symlink);
	    grub_free (ctx.symlink);
	    ctx.symlink = 0;
	    ctx.was_continue = 0;
	  }
	if (hook (ctx.filename, ctx.type, node, hook_data))
	  {
	    if (ctx.filename_alloc)
	      grub_free (ctx.filename);
	    return 1;
	  }
	if (ctx.filename_alloc)
	  grub_free (ctx.filename);
      }
    }
Пример #29
0
/* 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;
}
Пример #30
0
static grub_err_t
handle_symlink (struct grub_archelp_data *data,
		struct grub_archelp_ops *arcops,
		const char *fn, char **name,
		grub_uint32_t mode, int *restart)
{
  grub_size_t flen;
  char *target;
  char *ptr;
  char *lastslash;
  grub_size_t prefixlen;
  char *rest;
  char *linktarget;
  grub_size_t linktarget_len;

  *restart = 0;

  if ((mode & GRUB_ARCHELP_ATTR_TYPE) != GRUB_ARCHELP_ATTR_LNK
      || !arcops->get_link_target)
    return GRUB_ERR_NONE;
  flen = grub_strlen (fn);
  if (grub_memcmp (*name, fn, flen) != 0 
      || ((*name)[flen] != 0 && (*name)[flen] != '/'))
    return GRUB_ERR_NONE;
  rest = *name + flen;
  lastslash = rest;
  if (*rest)
    rest++;
  while (lastslash >= *name && *lastslash != '/')
    lastslash--;
  if (lastslash >= *name)
    prefixlen = lastslash - *name;
  else
    prefixlen = 0;

  if (prefixlen)
    prefixlen++;

  linktarget = arcops->get_link_target (data);
  if (!linktarget)
    return grub_errno;
  if (linktarget[0] == '\0')
    return GRUB_ERR_NONE;
  linktarget_len = grub_strlen (linktarget);
  target = grub_malloc (linktarget_len + grub_strlen (*name) + 2);
  if (!target)
    return grub_errno;

  grub_strcpy (target + prefixlen, linktarget);
  grub_free (linktarget);
  if (target[prefixlen] == '/')
    {
      ptr = grub_stpcpy (target, target + prefixlen);
      ptr = grub_stpcpy (ptr, rest);
      *ptr = 0;
      grub_dprintf ("archelp", "symlink redirected %s to %s\n",
		    *name, target);
      grub_free (*name);

      canonicalize (target);
      *name = target;
      *restart = 1;
      return GRUB_ERR_NONE;
    }
  if (prefixlen)
    {
      grub_memcpy (target, *name, prefixlen);
      target[prefixlen-1] = '/';
    }
  grub_strcpy (target + prefixlen + linktarget_len, rest);
  grub_dprintf ("archelp", "symlink redirected %s to %s\n",
		*name, target);
  grub_free (*name);
  canonicalize (target);
  *name = target;
  *restart = 1;
  return GRUB_ERR_NONE;
}