示例#1
0
文件: ofdisk.c 项目: flihp/grub2
static int
check_string_removable (const char *str)
{
  const char *ptr = grub_strrchr (str, '/');

  if (ptr)
    ptr++;
  else
    ptr = str;
  return (grub_strncmp (ptr, "cdrom", 5) == 0 || grub_strncmp (ptr, "fd", 2) == 0);
}
示例#2
0
  int putvar (const char *str, grub_size_t len)
  {
    const char *var;
    grub_size_t i;

    for (i = 0; i < nallowed_strings; i++)
      if (grub_strncmp (allowed_strings[i], str, len) == 0
	  && allowed_strings[i][len] == 0)
       	{
	  break;
	}
    if (i == nallowed_strings)
      return 0;

    /* Enough for any number.  */
    if (len == 1 && str[0] == '#')
      {
	grub_snprintf (ptr, 30, "%u", scope->argv.argc);
	ptr += grub_strlen (ptr);
	return 0;
      }
    var = grub_env_get (allowed_strings[i]);
    if (var)
      ptr = grub_stpcpy (ptr, var);
    return 0;
  }
示例#3
0
static int
check_option (const char *a, const char *b, grub_size_t len)
{
  if (grub_strlen (b) != len)
    return 0;
  return grub_strncmp (a, b, len) == 0;
}
示例#4
0
文件: ofdisk.c 项目: kphillisjr/burg
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;
}
示例#5
0
文件: ofdisk.c 项目: Arvian/GRUB2
static grub_err_t
grub_ofdisk_open (const char *name, grub_disk_t disk)
{
  grub_ieee1275_phandle_t dev;
  char *devpath;
  /* XXX: This should be large enough for any possible case.  */
  char prop[64];
  grub_ssize_t actual;

  if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0)
      return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
			 "not IEEE1275 device");
  devpath = compute_dev_path (name + sizeof ("ieee1275/") - 1);
  if (! devpath)
    return grub_errno;

  grub_dprintf ("disk", "Opening `%s'.\n", devpath);

  if (grub_ieee1275_finddevice (devpath, &dev))
    {
      grub_free (devpath);
      return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
			 "can't read device properties");
    }

  if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop),
				  &actual))
    {
      grub_free (devpath);
      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type");
    }

  if (grub_strcmp (prop, "block"))
    {
      grub_free (devpath);
      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device");
    }

  /* XXX: There is no property to read the number of blocks.  There
     should be a property `#blocks', but it is not there.  Perhaps it
     is possible to use seek for this.  */
  disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;

  {
    struct ofdisk_hash_ent *op;
    op = ofdisk_hash_find (devpath);
    if (!op)
      op = ofdisk_hash_add (devpath, NULL);
    else
      grub_free (devpath);
    if (!op)
      return grub_errno;
    disk->id = (unsigned long) op;
    disk->data = op->devpath;
  }

  return 0;
}
示例#6
0
static grub_err_t
grub_pxe_open (const char *name, grub_disk_t disk)
{
  struct grub_pxe_disk_data *data;

  if (grub_strcmp (name, "pxe") != 0
      && grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) != 0)
    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");

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

  if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0)
    {
      const char *ptr;
      grub_err_t err;

      ptr = name + sizeof ("pxe:") - 1;
      err = parse_ip (ptr, &(data->server_ip), &ptr);
      if (err)
	return err;
      if (*ptr == ':')
	{
	  err = parse_ip (ptr + 1, &(data->gateway_ip), 0);
	  if (err)
	    return err;
	}
      else
	data->gateway_ip = grub_pxe_default_gateway_ip;
    }
  else
    {
      data->server_ip = grub_pxe_default_server_ip;
      data->gateway_ip = grub_pxe_default_gateway_ip;
    }

  disk->total_sectors = 0;
  disk->id = (unsigned long) data;

  disk->has_partitions = 0;
  disk->data = data;

  return GRUB_ERR_NONE;
}
示例#7
0
文件: sfs.c 项目: DarkPostal/grub2
static struct grub_sfs_data *
grub_sfs_mount (grub_disk_t disk)
{
  struct grub_sfs_data *data;
  struct grub_sfs_objc *rootobjc;
  char *rootobjc_data = 0;
  unsigned int blk;

  data = grub_malloc (sizeof (*data));
  if (!data)
    return 0;

  /* Read the rootblock.  */
  grub_disk_read (disk, 0, 0, sizeof (struct grub_sfs_rblock),
		  (char *) &data->rblock);
  if (grub_errno)
    goto fail;

  /* Make sure this is a sfs filesystem.  */
  if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4))
    {
      grub_error (GRUB_ERR_BAD_FS, "not a sfs filesystem");
      goto fail;
    }

  data->blocksize = grub_be_to_cpu32 (data->rblock.blocksize);
  rootobjc_data = grub_malloc (data->blocksize);
  if (! rootobjc_data)
    goto fail;

  /* Read the root object container.  */
  grub_disk_read (disk, grub_be_to_cpu32 (data->rblock.rootobject), 0,
		  data->blocksize, rootobjc_data);
  if (grub_errno)
    goto fail;

  rootobjc = (struct grub_sfs_objc *) rootobjc_data;

  blk = grub_be_to_cpu32 (rootobjc->objects[0].file_dir.dir.dir_objc);
  data->diropen.size = 0;
  data->diropen.block = blk;
  data->diropen.data = data;
  data->disk = disk;
  data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));

  return data;

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

  grub_free (data);
  grub_free (rootobjc_data);
  return 0;
}
示例#8
0
static grub_err_t
susp_iterate_set_rockridge (struct grub_iso9660_susp_entry *susp_entry,
			    void *_data)
{
  struct grub_iso9660_data *data = _data;
  /* The "ER" entry is used to detect extensions.  The
     `IEEE_P1285' extension means Rock ridge.  */
  if (grub_strncmp ((char *) susp_entry->sig, "ER", 2) == 0)
    {
      data->rockridge = 1;
      return 1;
    }
  return 0;
}
示例#9
0
文件: help.c 项目: DarkPostal/grub2
  int print_command_help (grub_command_t cmd)
    {
      if (grub_command_find (cmd->name))
	{
	  if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg)))
	    {
	      if (cnt++ > 0)
		grub_printf ("\n\n");
	      
	      grub_arg_show_help (cmd);
	    }
	}
      return 0;
    }
示例#10
0
文件: ofdisk.c 项目: JoliOS/grub2
static int
grub_ofdisk_iterate (int (*hook) (const char *name))
{
    auto int dev_iterate (struct grub_ieee1275_devalias *alias);

    int dev_iterate (struct grub_ieee1275_devalias *alias)
    {
        int ret = 0;

        grub_dprintf ("disk", "disk name = %s\n", alias->name);

        if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
        {
            grub_ieee1275_phandle_t dev;
            char tmp[8];

            if (grub_ieee1275_finddevice (alias->path, &dev))
            {
                grub_dprintf ("disk", "finddevice (%s) failed\n", alias->path);
                return 0;
            }

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

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

        if (! grub_strcmp (alias->type, "block") &&
                grub_strncmp (alias->name, "cdrom", 5))
            ret = hook (alias->name);
        return ret;
    }
示例#11
0
  int getlen (const char *str, grub_size_t len)
  {
    const char *var;
    grub_size_t i;

    for (i = 0; i < nallowed_strings; i++)
      if (grub_strncmp (allowed_strings[i], str, len) == 0
	  && allowed_strings[i][len] == 0)
	break;
    if (i == nallowed_strings)
      return 0;

    /* Enough for any number.  */
    if (len == 1 && str[0] == '#')
      {
	additional_len += 30;
	return 0;
      }
    var = grub_env_get (allowed_strings[i]);
    if (var)
      additional_len += grub_strlen (var);
    return 0;
  }
示例#12
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;
  }
}
示例#13
0
文件: cmain.c 项目: kphillisjr/burg
static void
grub_ieee1275_find_options (void)
{
    grub_ieee1275_phandle_t root;
    grub_ieee1275_phandle_t options;
    grub_ieee1275_phandle_t openprom;
    grub_ieee1275_phandle_t bootrom;
    int rc;
    grub_uint32_t realmode = 0;
    char tmp[32];
    int is_smartfirmware = 0;
    int is_olpc = 0;
    int is_qemu = 0;

#ifdef __sparc__
    grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
#endif

    grub_ieee1275_finddevice ("/", &root);
    grub_ieee1275_finddevice ("/options", &options);
    grub_ieee1275_finddevice ("/openprom", &openprom);

    rc = grub_ieee1275_get_integer_property (options, "real-mode?", &realmode,
            sizeof realmode, 0);
    if (((rc >= 0) && realmode) || (grub_ieee1275_mmu == 0))
        grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE);

    rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright",
                                     tmp,	sizeof (tmp), 0);
    if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1))
        is_smartfirmware = 1;

    rc = grub_ieee1275_get_property (root, "architecture",
                                     tmp,	sizeof (tmp), 0);
    if (rc >= 0 && !grub_strcmp (tmp, "OLPC"))
        is_olpc = 1;

    rc = grub_ieee1275_get_property (root, "model",
                                     tmp,	sizeof (tmp), 0);
    if (rc >= 0 && !grub_strcmp (tmp, "Emulated PC"))
        is_qemu = 1;

    if (rc >= 0 && grub_strncmp (tmp, "IBM", 3) == 0)
        grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS);

    if (grub_strncmp (tmp, "PowerMac", sizeof ("PowerMac") - 1) == 0)
        grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS);

    if (is_smartfirmware)
    {
        /* Broken in all versions */
        grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);

        /* There are two incompatible ways of checking the version number.  Try
           both. */
        rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version",
                                         tmp, sizeof (tmp), 0);
        if (rc < 0)
            rc = grub_ieee1275_get_property (openprom, "firmware-version",
                                             tmp, sizeof (tmp), 0);
        if (rc >= 0)
        {
            /* It is tempting to implement a version parser to set the flags for
               e.g. 1.3 and below.  However, there's a special situation here.
               3rd party updates which fix the partition bugs are common, and for
               some reason their fixes aren't being merged into trunk.  So for
               example we know that 1.2 and 1.3 are broken, but there's 1.2.99
               and 1.3.99 which are known good (and applying this workaround
               would cause breakage). */
            if (!grub_strcmp (tmp, "1.0")
                    || !grub_strcmp (tmp, "1.1")
                    || !grub_strcmp (tmp, "1.2")
                    || !grub_strcmp (tmp, "1.3"))
            {
                grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
                grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS);
            }
        }
    }

    if (is_olpc)
    {
        /* OLPC / XO laptops have three kinds of storage devices:

        - NAND flash.  These are accessible via OFW callbacks, but:
           - Follow strange semantics, imposed by hardware constraints.
           - Its ABI is undocumented, and not stable.
           They lack "device_type" property, which conveniently makes GRUB
           skip them.

         - USB drives.  Not accessible, because OFW shuts down the controller
           in order to prevent collisions with applications accessing it
           directly.  Even worse, attempts to access it will NOT return
           control to the caller, so we have to avoid probing them.

         - SD cards.  These work fine.

         To avoid breakage, we only need to skip USB probing.  However,
         since detecting SD cards is more reliable, we do that instead.
            */

        grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY);
        grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF);
    }

    if (is_qemu)
    {
        /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB.  */
        grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM);

        grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF);
    }

    if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom))
    {
        rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0);
        if (rc >= 0 && !grub_strncmp (tmp, OHW, sizeof (OHW) - 1))
        {
            grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
            grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS);
            grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET);
            grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM);
            grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_ANSI);
        }
    }
}
示例#14
0
文件: partition.c 项目: P4N74/radare2
grub_partition_t
grub_partition_probe (struct grub_disk *disk, const char *str)
{
  grub_partition_t part = 0;
  grub_partition_t curpart = 0;
  grub_partition_t tail;
  const char *ptr;

  part = tail = disk->partition;

  for (ptr = str; *ptr;)
    {
      grub_partition_map_t partmap;
      int num;
      const char *partname, *partname_end;

      partname = ptr;
      while (*ptr && grub_isalpha (*ptr))
	ptr++;
      partname_end = ptr;
      num = grub_strtoul (ptr, (char **) &ptr, 0) - 1;

      curpart = 0;
      /* Use the first partition map type found.  */
      FOR_PARTITION_MAPS(partmap)
      {
	if (partname_end != partname &&
	    (grub_strncmp (partmap->name, partname, partname_end - partname)
	     != 0 || partmap->name[partname_end - partname] != 0))
	  continue;

	disk->partition = part;
	curpart = grub_partition_map_probe (partmap, disk, num);
	disk->partition = tail;
	if (curpart)
	  break;

	if (grub_errno == GRUB_ERR_BAD_PART_TABLE)
	  {
	    /* Continue to next partition map type.  */
	    grub_errno = GRUB_ERR_NONE;
	    continue;
	  }

	break;
      }

      if (! curpart)
	{
	  while (part)
	    {
	      curpart = part->parent;
	      grub_free (part);
	      part = curpart;
	    }
	  return 0;
	}
      curpart->parent = part;
      part = curpart;
      if (! ptr || *ptr != ',')
	break;
      ptr++;
    }

  return part;
}
示例#15
0
static grub_err_t
susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
		  void *_ctx)
{
  struct iterate_dir_ctx *ctx = _ctx;

  /* The filename in the rock ridge entry.  */
  if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0)
    {
      /* The flags are stored at the data position 0, here the
	 filename type is stored.  */
      /* FIXME: Fix this slightly improper cast.  */
      if (entry->data[0] & GRUB_ISO9660_RR_DOT)
	ctx->filename = (char *) ".";
      else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT)
	ctx->filename = (char *) "..";
      else if (entry->len >= 5)
	{
	  grub_size_t off = 0, csize = 1;
	  char *old;
	  csize = entry->len - 5;
	  old = ctx->filename;
	  if (ctx->filename_alloc)
	    {
	      off = grub_strlen (ctx->filename);
	      ctx->filename = grub_realloc (ctx->filename, csize + off + 1);
	    }
	  else
	    {
	      off = 0;
	      ctx->filename = grub_zalloc (csize + 1);
	    }
	  if (!ctx->filename)
	    {
	      ctx->filename = old;
	      return grub_errno;
	    }
	  ctx->filename_alloc = 1;
	  grub_memcpy (ctx->filename + off, (char *) &entry->data[1], csize);
	  ctx->filename[off + csize] = '\0';
	}
    }
  /* The mode information (st_mode).  */
  else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0)
    {
      /* At position 0 of the PX record the st_mode information is
	 stored (little-endian).  */
      grub_uint32_t mode = ((entry->data[0] + (entry->data[1] << 8))
			    & GRUB_ISO9660_FSTYPE_MASK);

      switch (mode)
	{
	case GRUB_ISO9660_FSTYPE_DIR:
	  ctx->type = GRUB_FSHELP_DIR;
	  break;
	case GRUB_ISO9660_FSTYPE_REG:
	  ctx->type = GRUB_FSHELP_REG;
	  break;
	case GRUB_ISO9660_FSTYPE_SYMLINK:
	  ctx->type = GRUB_FSHELP_SYMLINK;
	  break;
	default:
	  ctx->type = GRUB_FSHELP_UNKNOWN;
	}
    }
  else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0)
    {
      unsigned int pos = 1;

      /* The symlink is not stored as a POSIX symlink, translate it.  */
      while (pos + sizeof (*entry) < entry->len)
	{
	  /* The current position is the `Component Flag'.  */
	  switch (entry->data[pos] & 30)
	    {
	    case 0:
	      {
		/* The data on pos + 2 is the actual data, pos + 1
		   is the length.  Both are part of the `Component
		   Record'.  */
		if (ctx->symlink && !ctx->was_continue)
		  add_part (ctx, "/", 1);
		add_part (ctx, (char *) &entry->data[pos + 2],
			  entry->data[pos + 1]);
		ctx->was_continue = (entry->data[pos] & 1);
		break;
	      }

	    case 2:
	      add_part (ctx, "./", 2);
	      break;

	    case 4:
	      add_part (ctx, "../", 3);
	      break;

	    case 8:
	      add_part (ctx, "/", 1);
	      break;
	    }
	  /* In pos + 1 the length of the `Component Record' is
	     stored.  */
	  pos += entry->data[pos + 1] + 2;
	}

      /* Check if `grub_realloc' failed.  */
      if (grub_errno)
	return grub_errno;
    }

  return 0;
}
示例#16
0
static struct grub_iso9660_data *
grub_iso9660_mount (grub_disk_t disk)
{
  struct grub_iso9660_data *data = 0;
  struct grub_iso9660_primary_voldesc voldesc;
  int block;

  data = grub_zalloc (sizeof (struct grub_iso9660_data));
  if (! data)
    return 0;

  data->disk = disk;

  block = 16;
  do
    {
      int copy_voldesc = 0;

      /* Read the superblock.  */
      if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0,
			  sizeof (struct grub_iso9660_primary_voldesc),
			  (char *) &voldesc))
        {
          grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
          goto fail;
        }

      if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0)
        {
          grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
          goto fail;
        }

      if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY)
	copy_voldesc = 1;
      else if (!data->rockridge
	       && (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP)
	       && (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f)
	       &&
               ((voldesc.escape[2] == 0x40) ||	/* UCS-2 Level 1.  */
                (voldesc.escape[2] == 0x43) ||  /* UCS-2 Level 2.  */
                (voldesc.escape[2] == 0x45)))	/* UCS-2 Level 3.  */
        {
          copy_voldesc = 1;
          data->joliet = 1;
        }

      if (copy_voldesc)
	{
	  grub_memcpy((char *) &data->voldesc, (char *) &voldesc,
		      sizeof (struct grub_iso9660_primary_voldesc));
	  if (set_rockridge (data))
	    goto fail;
	}

      block++;
    } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END);

  return data;

 fail:
  grub_free (data);
  return 0;
}
示例#17
0
static grub_err_t
set_rockridge (struct grub_iso9660_data *data)
{
  int sua_pos;
  int sua_size;
  char *sua;
  struct grub_iso9660_dir rootdir;
  struct grub_iso9660_susp_entry *entry;

  data->rockridge = 0;

  /* Read the system use area and test it to see if SUSP is
     supported.  */
  if (grub_disk_read (data->disk,
		      (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
		       << GRUB_ISO9660_LOG2_BLKSZ), 0,
		      sizeof (rootdir), (char *) &rootdir))
    return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");

  sua_pos = (sizeof (rootdir) + rootdir.namelen
	     + (rootdir.namelen % 2) - 1);
  sua_size = rootdir.len - sua_pos;

  if (!sua_size)
    return GRUB_ERR_NONE;

  sua = grub_malloc (sua_size);
  if (! sua)
    return grub_errno;

  if (grub_disk_read (data->disk,
		      (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
		       << GRUB_ISO9660_LOG2_BLKSZ), sua_pos,
		      sua_size, sua))
    {
      grub_free (sua);
      return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
    }

  entry = (struct grub_iso9660_susp_entry *) sua;

  /* Test if the SUSP protocol is used on this filesystem.  */
  if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0)
    {
      struct grub_fshelp_node rootnode;

      rootnode.data = data;
      rootnode.alloc_dirents = ARRAY_SIZE (rootnode.dirents);
      rootnode.have_dirents = 1;
      rootnode.have_symlink = 0;
      rootnode.dirents[0] = data->voldesc.rootdir;

      /* The 2nd data byte stored how many bytes are skipped every time
	 to get to the SUA (System Usage Area).  */
      data->susp_skip = entry->data[2];
      entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len);

      /* Iterate over the entries in the SUA area to detect
	 extensions.  */
      if (grub_iso9660_susp_iterate (&rootnode,
				     sua_pos, sua_size, susp_iterate_set_rockridge,
				     data))
	{
	  grub_free (sua);
	  return grub_errno;
	}
    }
  grub_free (sua);
  return GRUB_ERR_NONE;
}
示例#18
0
/* Iterate over the susp entries, starting with block SUA_BLOCK on the
   offset SUA_POS with a size of SUA_SIZE bytes.  Hook is called for
   every entry.  */
static grub_err_t
grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off,
			   grub_ssize_t sua_size,
			   grub_err_t (*hook)
			   (struct grub_iso9660_susp_entry *entry, void *hook_arg),
			   void *hook_arg)
{
  char *sua;
  struct grub_iso9660_susp_entry *entry;
  grub_err_t err;

  if (sua_size <= 0)
    return GRUB_ERR_NONE;

  sua = grub_malloc (sua_size);
  if (!sua)
    return grub_errno;

  /* Load a part of the System Usage Area.  */
  err = read_node (node, off, sua_size, sua);
  if (err)
    return err;

  for (entry = (struct grub_iso9660_susp_entry *) sua; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0;
       entry = (struct grub_iso9660_susp_entry *)
	 ((char *) entry + entry->len))
    {
      /* The last entry.  */
      if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0)
	break;

      /* Additional entries are stored elsewhere.  */
      if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0)
	{
	  struct grub_iso9660_susp_ce *ce;
	  grub_disk_addr_t ce_block;

	  ce = (struct grub_iso9660_susp_ce *) entry;
	  sua_size = grub_le_to_cpu32 (ce->len);
	  off = grub_le_to_cpu32 (ce->off);
	  ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ;

	  grub_free (sua);
	  sua = grub_malloc (sua_size);
	  if (!sua)
	    return grub_errno;

	  /* Load a part of the System Usage Area.  */
	  err = grub_disk_read (node->data->disk, ce_block, off,
				sua_size, sua);
	  if (err)
	    return err;

	  entry = (struct grub_iso9660_susp_entry *) sua;
	}

      if (hook (entry, hook_arg))
	{
	  grub_free (sua);
	  return 0;
	}
    }

  grub_free (sua);
  return 0;
}
示例#19
0
文件: lvm.c 项目: jnbek/grub2-fedora
static struct grub_diskfilter_vg * 
grub_lvm_detect (grub_disk_t disk,
		 struct grub_diskfilter_pv_id *id,
		 grub_disk_addr_t *start_sector)
{
  grub_err_t err;
  grub_uint64_t mda_offset, mda_size;
  char buf[GRUB_LVM_LABEL_SIZE];
  char vg_id[GRUB_LVM_ID_STRLEN+1];
  char pv_id[GRUB_LVM_ID_STRLEN+1];
  char *metadatabuf, *p, *q, *vgname;
  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
  struct grub_lvm_pv_header *pvh;
  struct grub_lvm_disk_locn *dlocn;
  struct grub_lvm_mda_header *mdah;
  struct grub_lvm_raw_locn *rlocn;
  unsigned int i, j, vgname_len;
  struct grub_diskfilter_vg *vg;
  struct grub_diskfilter_pv *pv;

  /* Search for label. */
  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
    {
      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
      if (err)
	goto fail;

      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
			   sizeof (lh->id)))
	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
			      sizeof (lh->type))))
	break;
    }

  /* Return if we didn't find a label. */
  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
    {
#ifdef GRUB_UTIL
      grub_util_info ("no LVM signature found");
#endif
      goto fail;
    }

  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));

  for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
    {
      pv_id[j++] = pvh->pv_uuid[i];
      if ((i != 1) && (i != 29) && (i % 4 == 1))
	pv_id[j++] = '-';
    }
  pv_id[j] = '\0';

  dlocn = pvh->disk_areas_xl;

  dlocn++;
  /* Is it possible to have multiple data/metadata areas? I haven't
     seen devices that have it. */
  if (dlocn->offset)
    {
      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		  "we don't support multiple LVM data areas");

#ifdef GRUB_UTIL
      grub_util_info ("we don't support multiple LVM data areas\n");
#endif
      goto fail;
    }

  dlocn++;
  mda_offset = grub_le_to_cpu64 (dlocn->offset);
  mda_size = grub_le_to_cpu64 (dlocn->size);

  /* It's possible to have multiple copies of metadata areas, we just use the
     first one.  */

  /* Allocate buffer space for the circular worst-case scenario. */
  metadatabuf = grub_malloc (2 * mda_size);
  if (! metadatabuf)
    goto fail;

  err = grub_disk_read (disk, 0, mda_offset, mda_size, metadatabuf);
  if (err)
    goto fail2;

  mdah = (struct grub_lvm_mda_header *) metadatabuf;
  if ((grub_strncmp ((char *)mdah->magic, GRUB_LVM_FMTT_MAGIC,
		     sizeof (mdah->magic)))
      || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION))
    {
      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
		  "unknown LVM metadata header");
#ifdef GRUB_UTIL
      grub_util_info ("unknown LVM metadata header\n");
#endif
      goto fail2;
    }

  rlocn = mdah->raw_locns;
  if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) >
      grub_le_to_cpu64 (mdah->size))
    {
      /* Metadata is circular. Copy the wrap in place. */
      grub_memcpy (metadatabuf + mda_size,
		   metadatabuf + GRUB_LVM_MDA_HEADER_SIZE,
		   grub_le_to_cpu64 (rlocn->offset) +
		   grub_le_to_cpu64 (rlocn->size) -
		   grub_le_to_cpu64 (mdah->size));
    }
  p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);

  while (*q != ' ' && q < metadatabuf + mda_size)
    q++;

  if (q == metadatabuf + mda_size)
    {
#ifdef GRUB_UTIL
      grub_util_info ("error parsing metadata\n");
#endif
      goto fail2;
    }

  vgname_len = q - p;
  vgname = grub_malloc (vgname_len + 1);
  if (!vgname)
    goto fail2;

  grub_memcpy (vgname, p, vgname_len);
  vgname[vgname_len] = '\0';

  p = grub_strstr (q, "id = \"");
  if (p == NULL)
    {
#ifdef GRUB_UTIL
      grub_util_info ("couldn't find ID\n");
#endif
      goto fail3;
    }
  p += sizeof ("id = \"") - 1;
  grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN);
  vg_id[GRUB_LVM_ID_STRLEN] = '\0';

  vg = grub_diskfilter_get_vg_by_uuid (GRUB_LVM_ID_STRLEN, vg_id);

  if (! vg)
    {
      /* First time we see this volume group. We've to create the
	 whole volume group structure. */
      vg = grub_malloc (sizeof (*vg));
      if (! vg)
	goto fail3;
      vg->name = vgname;
      vg->uuid = grub_malloc (GRUB_LVM_ID_STRLEN);
      if (! vg->uuid)
	goto fail3;
      grub_memcpy (vg->uuid, vg_id, GRUB_LVM_ID_STRLEN);
      vg->uuid_len = GRUB_LVM_ID_STRLEN;

      vg->extent_size = grub_lvm_getvalue (&p, "extent_size = ");
      if (p == NULL)
	{
#ifdef GRUB_UTIL
	  grub_util_info ("unknown extent size\n");
#endif
	  goto fail4;
	}

      vg->lvs = NULL;
      vg->pvs = NULL;

      p = grub_strstr (p, "physical_volumes {");
      if (p)
	{
	  p += sizeof ("physical_volumes {") - 1;

	  /* Add all the pvs to the volume group. */
	  while (1)
	    {
	      int s;
	      while (grub_isspace (*p))
		p++;

	      if (*p == '}')
		break;

	      pv = grub_zalloc (sizeof (*pv));
	      q = p;
	      while (*q != ' ')
		q++;

	      s = q - p;
	      pv->name = grub_malloc (s + 1);
	      grub_memcpy (pv->name, p, s);
	      pv->name[s] = '\0';

	      p = grub_strstr (p, "id = \"");
	      if (p == NULL)
		goto pvs_fail;
	      p += sizeof("id = \"") - 1;

	      pv->id.uuid = grub_malloc (GRUB_LVM_ID_STRLEN);
	      if (!pv->id.uuid)
		goto pvs_fail;
	      grub_memcpy (pv->id.uuid, p, GRUB_LVM_ID_STRLEN);
	      pv->id.uuidlen = GRUB_LVM_ID_STRLEN;

	      pv->start_sector = grub_lvm_getvalue (&p, "pe_start = ");
	      if (p == NULL)
		{
#ifdef GRUB_UTIL
		  grub_util_info ("unknown pe_start\n");
#endif
		  goto pvs_fail;
		}

	      p = grub_strchr (p, '}');
	      if (p == NULL)
		{
#ifdef GRUB_UTIL
		  grub_util_info ("error parsing pe_start\n");
#endif
		  goto pvs_fail;
		}
	      p++;

	      pv->disk = NULL;
	      pv->next = vg->pvs;
	      vg->pvs = pv;

	      continue;
	    pvs_fail:
	      grub_free (pv->name);
	      grub_free (pv);
	      goto fail4;
	    }
	}

      p = grub_strstr (p, "logical_volumes");
      if (p)
	{
	  p += sizeof ("logical_volumes = ") - 1;

	  /* And add all the lvs to the volume group. */
	  while (1)
	    {
	      int s;
	      int skip_lv = 0;
	      struct grub_diskfilter_lv *lv;
	      struct grub_diskfilter_segment *seg;
	      int is_pvmove;

	      while (grub_isspace (*p))
		p++;

	      if (*p == '}')
		break;

	      lv = grub_zalloc (sizeof (*lv));

	      q = p;
	      while (*q != ' ')
		q++;

	      s = q - p;
	      lv->name = grub_strndup (p, s);
	      if (!lv->name)
		goto lvs_fail;

	      {
		const char *iptr;
		char *optr;
		lv->fullname = grub_malloc (sizeof ("lvm/") - 1 + 2 * vgname_len
					    + 1 + 2 * s + 1);
		if (!lv->fullname)
		  goto lvs_fail;

		grub_memcpy (lv->fullname, "lvm/", sizeof ("lvm/") - 1);
		optr = lv->fullname + sizeof ("lvm/") - 1;
		for (iptr = vgname; iptr < vgname + vgname_len; iptr++)
		  {
		    *optr++ = *iptr;
		    if (*iptr == '-')
		      *optr++ = '-';
		  }
		*optr++ = '-';
		for (iptr = p; iptr < p + s; iptr++)
		  {
		    *optr++ = *iptr;
		    if (*iptr == '-')
		      *optr++ = '-';
		  }
		*optr++ = 0;
		lv->idname = grub_malloc (sizeof ("lvmid/")
					  + 2 * GRUB_LVM_ID_STRLEN + 1);
		if (!lv->idname)
		  goto lvs_fail;
		grub_memcpy (lv->idname, "lvmid/",
			     sizeof ("lvmid/") - 1);
		grub_memcpy (lv->idname + sizeof ("lvmid/") - 1,
			     vg_id, GRUB_LVM_ID_STRLEN);
		lv->idname[sizeof ("lvmid/") - 1 + GRUB_LVM_ID_STRLEN] = '/';

		p = grub_strstr (q, "id = \"");
		if (p == NULL)
		  {
#ifdef GRUB_UTIL
		    grub_util_info ("couldn't find ID\n");
#endif
		    goto lvs_fail;
		  }
		p += sizeof ("id = \"") - 1;
		grub_memcpy (lv->idname + sizeof ("lvmid/") - 1
			     + GRUB_LVM_ID_STRLEN + 1,
			     p, GRUB_LVM_ID_STRLEN);
		lv->idname[sizeof ("lvmid/") - 1 + 2 * GRUB_LVM_ID_STRLEN + 1] = '\0';
	      }

	      lv->size = 0;

	      lv->visible = grub_lvm_check_flag (p, "status", "VISIBLE");
	      is_pvmove = grub_lvm_check_flag (p, "status", "PVMOVE");

	      lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
	      if (p == NULL)
		{
#ifdef GRUB_UTIL
		  grub_util_info ("unknown segment_count\n");
#endif
		  goto lvs_fail;
		}
	      lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
	      seg = lv->segments;

	      for (i = 0; i < lv->segment_count; i++)
		{

		  p = grub_strstr (p, "segment");
		  if (p == NULL)
		    {
#ifdef GRUB_UTIL
		      grub_util_info ("unknown segment\n");
#endif
		      goto lvs_segment_fail;
		    }

		  seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
		  if (p == NULL)
		    {
#ifdef GRUB_UTIL
		      grub_util_info ("unknown start_extent\n");
#endif
		      goto lvs_segment_fail;
		    }
		  seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
		  if (p == NULL)
		    {
#ifdef GRUB_UTIL
		      grub_util_info ("unknown extent_count\n");
#endif
		      goto lvs_segment_fail;
		    }

		  p = grub_strstr (p, "type = \"");
		  if (p == NULL)
		    goto lvs_segment_fail;
		  p += sizeof("type = \"") - 1;

		  lv->size += seg->extent_count * vg->extent_size;

		  if (grub_memcmp (p, "striped\"",
				   sizeof ("striped\"") - 1) == 0)
		    {
		      struct grub_diskfilter_node *stripe;

		      seg->type = GRUB_DISKFILTER_STRIPED;
		      seg->node_count = grub_lvm_getvalue (&p, "stripe_count = ");
		      if (p == NULL)
			{
#ifdef GRUB_UTIL
			  grub_util_info ("unknown stripe_count\n");
#endif
			  goto lvs_segment_fail;
			}

		      if (seg->node_count != 1)
			seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");

		      seg->nodes = grub_zalloc (sizeof (*stripe)
						* seg->node_count);
		      stripe = seg->nodes;

		      p = grub_strstr (p, "stripes = [");
		      if (p == NULL)
			{
#ifdef GRUB_UTIL
			  grub_util_info ("unknown stripes\n");
#endif
			  goto lvs_segment_fail2;
			}
		      p += sizeof("stripes = [") - 1;

		      for (j = 0; j < seg->node_count; j++)
			{
			  p = grub_strchr (p, '"');
			  if (p == NULL)
			    continue;
			  q = ++p;
			  while (*q != '"')
			    q++;

			  s = q - p;

			  stripe->name = grub_malloc (s + 1);
			  if (stripe->name == NULL)
			    goto lvs_segment_fail2;

			  grub_memcpy (stripe->name, p, s);
			  stripe->name[s] = '\0';

			  p = q + 1;

			  stripe->start = grub_lvm_getvalue (&p, ",")
			    * vg->extent_size;
			  if (p == NULL)
			    continue;

			  stripe++;
			}
		    }
		  else if (grub_memcmp (p, "mirror\"", sizeof ("mirror\"") - 1)
			   == 0)
		    {
		      seg->type = GRUB_DISKFILTER_MIRROR;
		      seg->node_count = grub_lvm_getvalue (&p, "mirror_count = ");
		      if (p == NULL)
			{
#ifdef GRUB_UTIL
			  grub_util_info ("unknown mirror_count\n");
#endif
			  goto lvs_segment_fail;
			}

		      seg->nodes = grub_zalloc (sizeof (seg->nodes[0])
						* seg->node_count);

		      p = grub_strstr (p, "mirrors = [");
		      if (p == NULL)
			{
#ifdef GRUB_UTIL
			  grub_util_info ("unknown mirrors\n");
#endif
			  goto lvs_segment_fail2;
			}
		      p += sizeof("mirrors = [") - 1;

		      for (j = 0; j < seg->node_count; j++)
			{
			  char *lvname;

			  p = grub_strchr (p, '"');
			  if (p == NULL)
			    continue;
			  q = ++p;
			  while (*q != '"')
			    q++;

			  s = q - p;

			  lvname = grub_malloc (s + 1);
			  if (lvname == NULL)
			    goto lvs_segment_fail2;

			  grub_memcpy (lvname, p, s);
			  lvname[s] = '\0';
			  seg->nodes[j].name = lvname;
			  p = q + 1;
			}
		      /* Only first (original) is ok with in progress pvmove.  */
		      if (is_pvmove)
			seg->node_count = 1;
		    }
		  else if (grub_memcmp (p, "raid", sizeof ("raid") - 1)
			   == 0 && (p[sizeof ("raid") - 1] >= '4'
				    && p[sizeof ("raid") - 1] <= '6')
			   && p[sizeof ("raidX") - 1] == '"')
		    {
		      switch (p[sizeof ("raid") - 1])
			{
			case '4':
			  seg->type = GRUB_DISKFILTER_RAID4;
			  seg->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC;
			  break;
			case '5':
			  seg->type = GRUB_DISKFILTER_RAID5;
			  seg->layout = GRUB_RAID_LAYOUT_LEFT_SYMMETRIC;
			  break;
			case '6':
			  seg->type = GRUB_DISKFILTER_RAID6;
			  seg->layout = (GRUB_RAID_LAYOUT_RIGHT_ASYMMETRIC
					 | GRUB_RAID_LAYOUT_MUL_FROM_POS);
			  break;
			}
		      seg->node_count = grub_lvm_getvalue (&p, "device_count = ");

		      if (p == NULL)
			{
#ifdef GRUB_UTIL
			  grub_util_info ("unknown device_count\n");
#endif
			  goto lvs_segment_fail;
			}

		      seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
		      if (p == NULL)
			{
#ifdef GRUB_UTIL
			  grub_util_info ("unknown stripe_size\n");
#endif
			  goto lvs_segment_fail;
			}


		      seg->nodes = grub_zalloc (sizeof (seg->nodes[0])
						* seg->node_count);

		      p = grub_strstr (p, "raids = [");
		      if (p == NULL)
			{
#ifdef GRUB_UTIL
			  grub_util_info ("unknown mirrors\n");
#endif
			  goto lvs_segment_fail2;
			}
		      p += sizeof("raids = [") - 1;

		      for (j = 0; j < seg->node_count; j++)
			{
			  char *lvname;

			  p = grub_strchr (p, '"');
			  p = p ? grub_strchr (p + 1, '"') : 0;
			  p = p ? grub_strchr (p + 1, '"') : 0;
			  if (p == NULL)
			    continue;
			  q = ++p;
			  while (*q != '"')
			    q++;

			  s = q - p;

			  lvname = grub_malloc (s + 1);
			  if (lvname == NULL)
			    goto lvs_segment_fail2;

			  grub_memcpy (lvname, p, s);
			  lvname[s] = '\0';
			  seg->nodes[j].name = lvname;
			  p = q + 1;
			}
		      if (seg->type == GRUB_DISKFILTER_RAID4)
			{
			  char *tmp;
			  tmp = seg->nodes[0].name;
			  grub_memmove (seg->nodes, seg->nodes + 1,
					sizeof (seg->nodes[0])
					* (seg->node_count - 1));
			  seg->nodes[seg->node_count - 1].name = tmp;
			}
		    }
		  else
		    {
#ifdef GRUB_UTIL
		      char *p2;
		      p2 = grub_strchr (p, '"');
		      if (p2)
			*p2 = 0;
		      grub_util_info ("unknown LVM type %s\n", p);
		      if (p2)
			*p2 ='"';
#endif
		      /* Found a non-supported type, give up and move on. */
		      skip_lv = 1;
		      break;
		    }

		  seg++;

		  continue;
		lvs_segment_fail2:
		  grub_free (seg->nodes);
		lvs_segment_fail:
		  goto fail4;
		}

	      if (p != NULL)
		p = grub_strchr (p, '}');
	      if (p == NULL)
		goto lvs_fail;
	      p += 3;

	      if (skip_lv)
		{
		  grub_free (lv->name);
		  grub_free (lv);
		  continue;
		}

	      lv->vg = vg;
	      lv->next = vg->lvs;
	      vg->lvs = lv;

	      continue;
	    lvs_fail:
	      grub_free (lv->name);
	      grub_free (lv);
	      goto fail4;
	    }
	}

      /* Match lvs.  */
      {
	struct grub_diskfilter_lv *lv1;
	struct grub_diskfilter_lv *lv2;
	for (lv1 = vg->lvs; lv1; lv1 = lv1->next)
	  for (i = 0; i < lv1->segment_count; i++)
	    for (j = 0; j < lv1->segments[i].node_count; j++)
	      {
		if (vg->pvs)
		  for (pv = vg->pvs; pv; pv = pv->next)
		    {
		      if (! grub_strcmp (pv->name,
					 lv1->segments[i].nodes[j].name))
			{
			  lv1->segments[i].nodes[j].pv = pv;
			  break;
			}
		    }
		if (lv1->segments[i].nodes[j].pv == NULL)
		  for (lv2 = vg->lvs; lv2; lv2 = lv2->next)
		    if (grub_strcmp (lv2->name,
				     lv1->segments[i].nodes[j].name) == 0)
		      lv1->segments[i].nodes[j].lv = lv2;
	      }
	
      }
      if (grub_diskfilter_vg_register (vg))
	goto fail4;
    }
  else
    {
      grub_free (vgname);
    }

  id->uuid = grub_malloc (GRUB_LVM_ID_STRLEN);
  if (!id->uuid)
    goto fail4;
  grub_memcpy (id->uuid, pv_id, GRUB_LVM_ID_STRLEN);
  id->uuidlen = GRUB_LVM_ID_STRLEN;
  grub_free (metadatabuf);
  *start_sector = -1;
  return vg;

  /* Failure path.  */
 fail4:
  grub_free (vg);
 fail3:
  grub_free (vgname);

 fail2:
  grub_free (metadatabuf);
 fail:
  return NULL;
}
示例#20
0
void
grub_util_pull_lvm_by_command (const char *os_dev)
{
  const char *argv[8];
  int fd;
  pid_t pid;
  FILE *vgs;
  char *buf = NULL;
  size_t len = 0;
  char *vgname = NULL;
  const char *iptr;
  char *optr;
  char *vgid = NULL;
  grub_size_t vgidlen = 0;

  vgid = grub_util_get_vg_uuid (os_dev);
  if (vgid)
    vgidlen = grub_strlen (vgid);

  if (!vgid)
    {
      if (strncmp (os_dev, LVM_DEV_MAPPER_STRING,
		   sizeof (LVM_DEV_MAPPER_STRING) - 1)
	  != 0)
	return;

      vgname = xmalloc (strlen (os_dev + sizeof (LVM_DEV_MAPPER_STRING) - 1) + 1);
      for (iptr = os_dev + sizeof (LVM_DEV_MAPPER_STRING) - 1, optr = vgname; *iptr; )
	if (*iptr != '-')
	  *optr++ = *iptr++;
	else if (iptr[0] == '-' && iptr[1] == '-')
	  {
	    iptr += 2;
	    *optr++ = '-';
	  }
	else
	  break;
      *optr = '\0';
    }

  /* by default PV name is left aligned in 10 character field, meaning that
     we do not know where name ends. Using dummy --separator disables
     alignment. We have a single field, so separator itself is not output */
  argv[0] = "vgs";
  argv[1] = "--options";
  if (vgid)
    argv[2] = "vg_uuid,pv_name";
  else
    argv[2] = "pv_name";
  argv[3] = "--noheadings";
  argv[4] = "--separator";
  argv[5] = ":";
  argv[6] = vgname;
  argv[7] = NULL;

  pid = grub_util_exec_pipe (argv, &fd);
  free (vgname);

  if (!pid)
    return;

  /* Parent.  Read vgs' output.  */
  vgs = fdopen (fd, "r");
  if (! vgs)
    {
      grub_util_warn (_("Unable to open stream from %s: %s"),
		      "vgs", strerror (errno));
      goto out;
    }

  while (getline (&buf, &len, vgs) > 0)
    {
      char *ptr;
      /* LVM adds two spaces as standard prefix */
      for (ptr = buf; ptr < buf + 2 && *ptr == ' '; ptr++);

      if (vgid && (grub_strncmp (vgid, ptr, vgidlen) != 0
		   || ptr[vgidlen] != ':'))
	continue;
      if (vgid)
	ptr += vgidlen + 1;
      if (*ptr == '\0')
	continue;
      *(ptr + strlen (ptr) - 1) = '\0';
      grub_util_pull_device (ptr);
    }

out:
  close (fd);
  waitpid (pid, NULL, 0);
  free (buf);
}
示例#21
0
文件: help.c 项目: AlfredArouna/grub2
static grub_err_t
grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
	       char **args)
{
  int cnt = 0;
  char *currarg;

  auto int print_command_info (grub_command_t cmd);
  auto int print_command_help (grub_command_t cmd);

  int print_command_info (grub_command_t cmd)
    {
      if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
	  (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
	{
	  struct grub_term_output *term;
	  const char *summary_translated = _(cmd->summary);
	  char *command_help;
	  grub_uint32_t *unicode_command_help;
	  grub_uint32_t *unicode_last_position;
	  			      
	  command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated);
	  if (!command_help)
	    return 1;

	  grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
	  			   &unicode_last_position);

	  FOR_ACTIVE_TERM_OUTPUTS(term)
	  {
	    unsigned stringwidth;
	    grub_uint32_t *unicode_last_screen_position;

	    unicode_last_screen_position = unicode_command_help;

	    stringwidth = 0;

	    while (unicode_last_screen_position < unicode_last_position && 
		   stringwidth < ((grub_term_width (term) / 2) - 2))
	      {
		stringwidth
		  += grub_term_getcharwidth (term,
					     *unicode_last_screen_position);
		unicode_last_screen_position++;
	      }

	    grub_print_ucs4 (unicode_command_help,
			     unicode_last_screen_position, term);
	    if (!(cnt % 2))
	      grub_print_spaces (term, grub_term_width (term) / 2
				 - stringwidth);
	  }
	  if (cnt % 2)
	    grub_printf ("\n");
	  cnt++;
	  
	  grub_free (command_help);
	  grub_free (unicode_command_help);
	}
      return 0;
    }

  int print_command_help (grub_command_t cmd)
    {
      if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
	{
	  if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg)))
	    {
	      if (cnt++ > 0)
		grub_printf ("\n\n");

	      if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
		grub_arg_show_help ((grub_extcmd_t) cmd->data);
	      else
		grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary),
			     _(cmd->description));
	    }
	}
      return 0;
    }

  if (argc == 0)
    {
      grub_command_iterate (print_command_info);
      if (!(cnt % 2))
	grub_printf ("\n");
    }
  else
    {
      int i;

      for (i = 0; i < argc; i++)
	{
	  currarg = args[i];
	  grub_command_iterate (print_command_help);
	}
    }

  return 0;
}
示例#22
0
/*
 * Given the nul-terminated input string s, expand all variable references
 * within that string into the buffer pointed to by d, which must be of length
 * not less than len bytes.
 *
 * We also expand the special case tokens "$ISADIR" and "$ZFS-BOOTFS" here.
 *
 * If the string will not fit, returns ERR_WONT_FIT.
 * If a nonexistent variable is referenced, returns ERR_NOVAR.
 * Otherwise, returns 0.  The resulting string is nul-terminated.  On error,
 * the contents of the destination buffer are undefined.
 */
int
expand_string(const char *s, char *d, unsigned int len)
{
	unsigned int i;
	int vlen;
	const char *p;
	char *q;
	const char *start;
	char name[EV_NAMELEN];
	const char *val;

	for (p = s, q = d; *p != '\0' && q < d + len; ) {
		/* Special case: $ISADIR */
		if (grub_strncmp(p, "$ISADIR", 7) == 0) {
			if (isamd64() && check_min_mem64()) {
				if (q + 5 >= d + len)
					return (ERR_WONT_FIT);
				(void) grub_memcpy(q, "amd64", 5);
				q += 5;	/* amd64 */
			}
			p += 7;	/* $ISADIR */
			continue;
		}
		/* Special case: $ZFS-BOOTFS */
		if (grub_strncmp(p, "$ZFS-BOOTFS", 11) == 0 &&
		    is_zfs_mount != 0) {
			if (current_bootpath[0] == '\0' &&
			    current_devid[0] == '\0') {
				return (ERR_NO_BOOTPATH);
			}

			/* zfs-bootfs=%s/%u */
			vlen = (current_bootfs_obj > 0) ? 10 : 0;
			vlen += 11;
			vlen += strlen(current_rootpool);

			/* ,bootpath=\"%s\" */
			if (current_bootpath[0] != '\0')
				vlen += 12 + strlen(current_bootpath);

			/* ,diskdevid=\"%s\" */
			if (current_devid[0] != '\0')
				vlen += 13 + strlen(current_devid);

			if (q + vlen >= d + len)
				return (ERR_WONT_FIT);

			if (current_bootfs_obj > 0) {
				q += grub_sprintf(q, "zfs-bootfs=%s/%u",
				    current_rootpool, current_bootfs_obj);
			} else {
				q += grub_sprintf(q, "zfs-bootfs=%s",
				    current_rootpool);
			}
			if (current_bootpath[0] != '\0') {
				q += grub_sprintf(q, ",bootpath=\"%s\"",
				    current_bootpath);
			}
			if (current_devid[0] != '\0') {
				q += grub_sprintf(q, ",diskdevid=\"%s\"",
				    current_devid);
			}

			p += 11;	/* $ZFS-BOOTFS */
			continue;
		}
		if (*p == '$' && *(p + 1) == '{') {
			start = p + 2;
			for (p = start; *p != '\0' && *p != '}' &&
			    p - start < sizeof (name) - 1; p++) {
				name[p - start] = *p;
			}
			/*
			 * Unterminated reference.  Copy verbatim.
			 */
			if (p - start >= sizeof (name) - 1 || *p != '}') {
				p = start;
				*q++ = '$';
				*q++ = '{';
				continue;
			}

			name[p - start] = '\0';
			val = get_variable(name);
			if (val == NULL)
				return (ERR_NOVAR);

			if ((vlen = grub_strlen(val)) >= q + len - d)
				return (ERR_WONT_FIT);

			(void) grub_memcpy(q, val, vlen);
			q += vlen;
			p++;
		} else {
			*q++ = *p++;
		}
	}

	if (q >= d + len)
		return (ERR_WONT_FIT);

	*q = '\0';

	return (0);
}
示例#23
0
static grub_err_t
parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
		 grub_off_t off, grub_size_t sz)
{
  char *buf;
  char *ptr;
  int has_paddr = 0;
  if (grub_file_seek (elf->file, off) == (grub_off_t) -1)
    return grub_errno;
  buf = grub_malloc (sz);
  if (!buf)
    return grub_errno;

  if (grub_file_read (elf->file, buf, sz) != (grub_ssize_t) sz)
    {
      if (grub_errno)
	return grub_errno;
      return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
			 elf->file->name);
    }
  xi->has_xen_guest = 1;
  for (ptr = buf; ptr && ptr - buf < (grub_ssize_t) sz;
       ptr = grub_strchr (ptr, ','), (ptr ? ptr++ : 0))
    {
      if (grub_strncmp (ptr, "PAE=no,", sizeof ("PAE=no,") - 1) == 0)
	{
	  if (xi->arch != GRUB_XEN_FILE_I386
	      && xi->arch != GRUB_XEN_FILE_I386_PAE
	      && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE)
	    continue;
	  xi->arch = GRUB_XEN_FILE_I386;
	  continue;
	}

      if (grub_strncmp (ptr, "PAE=yes,", sizeof ("PAE=yes,") - 1) == 0)
	{
	  if (xi->arch != GRUB_XEN_FILE_I386
	      && xi->arch != GRUB_XEN_FILE_I386_PAE
	      && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE)
	    continue;
	  xi->arch = GRUB_XEN_FILE_I386_PAE;
	  continue;
	}

      if (grub_strncmp (ptr, "PAE=yes[extended-cr3],",
			sizeof ("PAE=yes[extended-cr3],") - 1) == 0)
	{
	  if (xi->arch != GRUB_XEN_FILE_I386
	      && xi->arch != GRUB_XEN_FILE_I386_PAE
	      && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE)
	    continue;
	  xi->arch = GRUB_XEN_FILE_I386_PAE;
	  xi->extended_cr3 = 1;
	  continue;
	}

      if (grub_strncmp (ptr, "PAE=bimodal,", sizeof ("PAE=bimodal,") - 1) == 0)
	{
	  if (xi->arch != GRUB_XEN_FILE_I386
	      && xi->arch != GRUB_XEN_FILE_I386_PAE
	      && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE)
	    continue;
	  xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE;
	  continue;
	}

      if (grub_strncmp (ptr, "PAE=bimodal[extended-cr3],",
			sizeof ("PAE=bimodal[extended-cr3],") - 1) == 0)
	{
	  if (xi->arch != GRUB_XEN_FILE_I386
	      && xi->arch != GRUB_XEN_FILE_I386_PAE
	      && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE)
	    continue;
	  xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE;
	  xi->extended_cr3 = 1;
	  continue;
	}

      if (grub_strncmp (ptr, "PAE=yes,bimodal,", sizeof ("PAE=yes,bimodal,") - 1) == 0)
	{
	  if (xi->arch != GRUB_XEN_FILE_I386
	      && xi->arch != GRUB_XEN_FILE_I386_PAE
	      && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE)
	    continue;
	  xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE;
	  continue;
	}

      if (grub_strncmp (ptr, "PAE=yes[extended-cr3],bimodal,",
			sizeof ("PAE=yes[extended-cr3],bimodal,") - 1) == 0)
	{
	  if (xi->arch != GRUB_XEN_FILE_I386
	      && xi->arch != GRUB_XEN_FILE_I386_PAE
	      && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE)
	    continue;
	  xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE;
	  xi->extended_cr3 = 1;
	  continue;
	}

      if (grub_strncmp (ptr, "VIRT_BASE=", sizeof ("VIRT_BASE=") - 1) == 0)
	{
	  xi->virt_base = grub_strtoull (ptr + sizeof ("VIRT_BASE=") - 1, &ptr, 16);
	  if (grub_errno)
	    return grub_errno;
	  continue;
	}
      if (grub_strncmp (ptr, "VIRT_ENTRY=", sizeof ("VIRT_ENTRY=") - 1) == 0)
	{
	  xi->entry_point = grub_strtoull (ptr + sizeof ("VIRT_ENTRY=") - 1, &ptr, 16);
	  if (grub_errno)
	    return grub_errno;
	  continue;
	}
      if (grub_strncmp (ptr, "HYPERCALL_PAGE=", sizeof ("HYPERCALL_PAGE=") - 1) == 0)
	{
	  xi->hypercall_page = grub_strtoull (ptr + sizeof ("HYPERCALL_PAGE=") - 1, &ptr, 16);
	  xi->has_hypercall_page = 1;
	  if (grub_errno)
	    return grub_errno;
	  continue;
	}
      if (grub_strncmp (ptr, "ELF_PADDR_OFFSET=", sizeof ("ELF_PADDR_OFFSET=") - 1) == 0)
	{
	  xi->paddr_offset = grub_strtoull (ptr + sizeof ("ELF_PADDR_OFFSET=") - 1, &ptr, 16);
	  has_paddr = 1;
	  if (grub_errno)
	    return grub_errno;
	  continue;
	}
    }
  if (xi->has_hypercall_page)
    xi->hypercall_page = (xi->hypercall_page << 12) + xi->virt_base;
  if (!has_paddr)
    xi->paddr_offset = xi->virt_base;
  return GRUB_ERR_NONE;
}
示例#24
0
文件: affs.c 项目: kissthink/os-grub2
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;
}
示例#25
0
文件: setpci.c 项目: Spacy/grub-fuse
static grub_err_t
grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
{
  const char *ptr;
  unsigned i;

  pciid_check_value = 0;
  pciid_check_mask = 0;

  if (ctxt->state[0].set)
    {
      ptr = ctxt->state[0].arg;
      pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
      if (grub_errno == GRUB_ERR_BAD_NUMBER)
	{
	  grub_errno = GRUB_ERR_NONE;
	  ptr = ctxt->state[0].arg;
	}
      else
	pciid_check_mask |= 0xffff;
      if (grub_errno)
	return grub_errno;
      if (*ptr != ':')
	return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected.");
      ptr++;
      pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff)
	<< 16;
      if (grub_errno == GRUB_ERR_BAD_NUMBER)
	grub_errno = GRUB_ERR_NONE;
      else
	pciid_check_mask |= 0xffff0000;
    }

  pciid_check_value &= pciid_check_mask;

  check_bus = check_device = check_function = 0;

  if (ctxt->state[1].set)
    {
      const char *optr;
      
      ptr = ctxt->state[1].arg;
      optr = ptr;
      bus = grub_strtoul (ptr, (char **) &ptr, 16);
      if (grub_errno == GRUB_ERR_BAD_NUMBER)
	{
	  grub_errno = GRUB_ERR_NONE;
	  ptr = optr;
	}
      else
	check_bus = 1;
      if (grub_errno)
	return grub_errno;
      if (*ptr != ':')
	return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected.");
      ptr++;
      optr = ptr;
      device = grub_strtoul (ptr, (char **) &ptr, 16);
      if (grub_errno == GRUB_ERR_BAD_NUMBER)
	{
	  grub_errno = GRUB_ERR_NONE;
	  ptr = optr;
	}
      else
	check_device = 1;
      if (*ptr == '.')
	{
	  ptr++;
	  function = grub_strtoul (ptr, (char **) &ptr, 16);
	  if (grub_errno)
	    return grub_errno;
	  check_function = 1;
	}
    }

  if (ctxt->state[2].set)
    varname = ctxt->state[2].arg;
  else
    varname = NULL;

  write_mask = 0;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Command expected.");

  if (argc > 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one command is supported.");

  ptr = argv[0];

  for (i = 0; i < ARRAY_SIZE (pci_registers); i++)
    {
      if (grub_strncmp (ptr, pci_registers[i].name,
			grub_strlen (pci_registers[i].name)) == 0)
	break;
    }
  if (i == ARRAY_SIZE (pci_registers))
    {
      regsize = 0;
      regaddr = grub_strtoul (ptr, (char **) &ptr, 16);
      if (grub_errno)
	return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown register");
    }
  else
    {
      regaddr = pci_registers[i].addr;
      regsize = pci_registers[i].size;
      ptr += grub_strlen (pci_registers[i].name);
    }

  if (grub_errno)
    return grub_errno;

  if (*ptr == '+')
    {
      ptr++;
      regaddr += grub_strtoul (ptr, (char **) &ptr, 16);
      if (grub_errno)
	return grub_errno;
    }

  if (grub_memcmp (ptr, ".L", sizeof (".L") - 1) == 0
      || grub_memcmp (ptr, ".l", sizeof (".l") - 1) == 0)
    {
      regsize = 4;
      ptr += sizeof (".l") - 1;
    }
  else if (grub_memcmp (ptr, ".W", sizeof (".W") - 1) == 0
      || grub_memcmp (ptr, ".w", sizeof (".w") - 1) == 0)
    {
      regsize = 2;
      ptr += sizeof (".w") - 1;
    }
  else if (grub_memcmp (ptr, ".B", sizeof (".B") - 1) == 0
      || grub_memcmp (ptr, ".b", sizeof (".b") - 1) == 0)
    {
      regsize = 1;
      ptr += sizeof (".b") - 1;
    }

  if (!regsize)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
		       "Unknown register size.");

  write_mask = 0;
  if (*ptr == '=')
    {
      ptr++;
      regwrite = grub_strtoul (ptr, (char **) &ptr, 16);
      if (grub_errno)
	return grub_errno;
      write_mask = 0xffffffff;
      if (*ptr == ':')
	{
	  ptr++;
	  write_mask = grub_strtoul (ptr, (char **) &ptr, 16);
	  if (grub_errno)
	    return grub_errno;
	  write_mask = 0xffffffff;
	}
      regwrite &= write_mask;
    }

  if (write_mask && varname)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
		       "Option -v isn't valid for writes.");

  grub_pci_iterate (grub_setpci_iter);
  return GRUB_ERR_NONE;
}