Example #1
0
/* Return a new heap-allocated string representing to absolute path
   to the file referred to by PATH.  If PATH is an absolute path, then
   the returned path is a copy of PATH.  If PATH is a relative path, then
   BASE is with PATH used to construct the absolute path.  */
char *
grub_resolve_relative_path (const char *base, const char *path)
{
  char *abspath;
  char *canonpath;
  char *p;
  grub_size_t l;

  /* If PATH is an absolute path, then just use it as is.  */
  if (path[0] == '/' || path[0] == '(')
    return canonicalize_path (path);

  abspath = grub_malloc (grub_strlen (base) + grub_strlen (path) + 3);
  if (! abspath)
    return 0;

  /* Concatenate BASE and PATH.  */
  p = grub_stpcpy (abspath, base);
  l = grub_strlen (abspath);
  if (l == 0 || abspath[l-1] != '/')
    {
      *p = '/';
      p++;
      *p = 0;
    }
  grub_stpcpy (p, path);

  canonpath = canonicalize_path (abspath);
  if (! canonpath)
    return abspath;

  grub_free (abspath);
  return canonpath;
}
Example #2
0
File: ofdisk.c Project: flihp/grub2
static struct ofdisk_hash_ent *
ofdisk_hash_add_real (char *devpath)
{
  struct ofdisk_hash_ent *p;
  struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
  const char *iptr;
  char *optr;

  p = grub_zalloc (sizeof (*p));
  if (!p)
    return NULL;

  p->devpath = devpath;

  p->grub_devpath = grub_malloc (sizeof ("ieee1275/")
				 + 2 * grub_strlen (p->devpath));

  if (!p->grub_devpath)
    {
      grub_free (p);
      return NULL;
    }

  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
    {
      p->open_path = grub_malloc (grub_strlen (p->devpath) + 3);
      if (!p->open_path)
	{
	  grub_free (p->grub_devpath);
	  grub_free (p);
	  return NULL;
	}
      optr = grub_stpcpy (p->open_path, p->devpath);
      *optr++ = ':';
      *optr++ = '0';
      *optr = '\0';
    }
  else
    p->open_path = p->devpath;

  optr = grub_stpcpy (p->grub_devpath, "ieee1275/");
  for (iptr = p->devpath; *iptr; )
    {
      if (*iptr == ',')
	*optr++ = '\\';
      *optr++ = *iptr++;
    }
  *optr = 0;

  p->next = *head;
  *head = p;
  return p;
}
Example #3
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;
  }
Example #4
0
grub_err_t
grub_multiboot_init_mbi (int argc, char *argv[])
{
  grub_ssize_t len = 0;
  char *p;
  int i;

  grub_multiboot_free_mbi ();

  for (i = 0; i < argc; i++)
    len += grub_strlen (argv[i]) + 1;
  if (len == 0)
    len = 1;

  cmdline = p = grub_malloc (len);
  if (! cmdline)
    return grub_errno;
  cmdline_size = len;

  for (i = 0; i < argc; i++)
    {
      p = grub_stpcpy (p, argv[i]);
      *(p++) = ' ';
    }

  /* Remove the space after the last word.  */
  if (p != cmdline)
    p--;
  *p = '\0';

  return GRUB_ERR_NONE;
}
Example #5
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;
}
Example #6
0
grub_err_t
grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
			   int argc, char *argv[])
{
  struct module *newmod;
  char *p;
  grub_ssize_t len = 0;
  int i;

  newmod = grub_malloc (sizeof (*newmod));
  if (!newmod)
    return grub_errno;
  newmod->start = start;
  newmod->size = size;

  for (i = 0; i < argc; i++)
    len += grub_strlen (argv[i]) + 1;

  if (len == 0)
    len = 1;

  newmod->cmdline = p = grub_malloc (len);
  if (! newmod->cmdline)
    {
      grub_free (newmod);
      return grub_errno;
    }
  newmod->cmdline_size = len;
  total_modcmd += ALIGN_UP (len, 4);

  for (i = 0; i < argc; i++)
    {
      p = grub_stpcpy (p, argv[i]);
      *(p++) = ' ';
    }

  /* Remove the space after the last word.  */
  if (p != newmod->cmdline)
    p--;
  *p = '\0';

  if (modules_last)
    modules_last->next = newmod;
  else
    {
      modules = newmod;
      modules_last->next = NULL;
    }
  modules_last = newmod;

  modcnt++;

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

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

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

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

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

  return scaled_bitmap;
}
Example #8
0
char *
grub_util_get_devmapper_grub_dev (const char *os_dev)
{
  char *uuid, *optr;
  char *grub_dev;

  uuid = get_dm_uuid (os_dev);
  if (!uuid)
    return NULL;
  
  if (strncmp (uuid, "LVM-", sizeof ("LVM-") - 1) == 0)
    {
	unsigned i;
	int dashes[] = { 0, 6, 10, 14, 18, 22, 26, 32, 38, 42, 46, 50, 54, 58};
	grub_dev = xmalloc (grub_strlen (uuid) + 40);
	optr = grub_stpcpy (grub_dev, "lvmid/");
	for (i = 0; i < ARRAY_SIZE (dashes) - 1; i++)
	  {
	    memcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i],
		    dashes[i+1] - dashes[i]);
	    optr += dashes[i+1] - dashes[i];
	    *optr++ = '-';
	  }
	optr = stpcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i]);
	*optr = '\0';
	grub_dev[sizeof("lvmid/xxxxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxxxx") - 1]
	  = '/';
	free (uuid);
	return grub_dev;
      }

  if (strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0)
    {
      char *dash;
      dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-');
      if (dash)
	*dash = 0;
      grub_dev = grub_xasprintf ("cryptouuid/%s",
				 uuid + sizeof ("CRYPT-LUKS1-") - 1);
      grub_free (uuid);
      return grub_dev;
    }
  grub_free (uuid);
  return NULL;
}
Example #9
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;
}
Example #10
0
static void
probe (const char *path, char **device_names, char delim)
{
  char **drives_names = NULL;
  char **curdev, **curdrive;
  char *grub_path = NULL;
  int ndev = 0;

  if (path != NULL)
    {
      grub_path = canonicalize_file_name (path);
      if (! grub_path)
	grub_util_error (_("failed to get canonical path of `%s'"), path);
      device_names = grub_guess_root_devices (grub_path);
      free (grub_path);
    }

  if (! device_names)
    grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);

  if (print == PRINT_DEVICE)
    {
      for (curdev = device_names; *curdev; curdev++)
	{
	  printf ("%s", *curdev);
	  putchar (delim);
	}
      return;
    }

  if (print == PRINT_DISK)
    {
      for (curdev = device_names; *curdev; curdev++)
	{
	  char *disk;
	  disk = grub_util_get_os_disk (*curdev);
	  if (!disk)
	    {
	      grub_print_error ();
	      continue;
	    }
	  printf ("%s", disk);
	  putchar (delim);
	}
      return;
    }

  for (curdev = device_names; *curdev; curdev++)
    {
      grub_util_pull_device (*curdev);
      ndev++;
    }
  
  drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1)); 

  for (curdev = device_names, curdrive = drives_names; *curdev; curdev++,
       curdrive++)
    {
      *curdrive = grub_util_get_grub_dev (*curdev);
      if (! *curdrive)
	grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
			 *curdev);
    }
  *curdrive = 0;

  if (print == PRINT_DRIVE)
    {
      for (curdrive = drives_names; *curdrive; curdrive++)
	{
	  printf ("(%s)", *curdrive);
	  putchar (delim);
	}
      goto end;
    }

  if (print == PRINT_ZERO_CHECK)
    {
      for (curdev = drives_names; *curdev; curdev++)
	{
	  grub_device_t dev = NULL;
	  grub_uint32_t buffer[32768];
	  grub_disk_addr_t addr;
	  grub_disk_addr_t dsize;

	  grub_util_info ("opening %s", *curdev);
	  dev = grub_device_open (*curdev);
	  if (! dev || !dev->disk)
	    grub_util_error ("%s", grub_errmsg);

	  dsize = grub_disk_get_size (dev->disk);
	  for (addr = 0; addr < dsize;
	       addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE)
	    {
	      grub_size_t sz = sizeof (buffer);
	      grub_uint32_t *ptr;

	      if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr)
		sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE;
	      grub_disk_read (dev->disk, addr, 0, sz, buffer);

	      for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++)
		if (*ptr)
		  {
		    grub_printf ("false\n");
		    grub_device_close (dev);
		    goto end;
		  }
	    }

	  grub_device_close (dev);
	}
      grub_printf ("true\n");
    }

  if (print == PRINT_FS || print == PRINT_FS_UUID
      || print == PRINT_FS_LABEL)
    {
      grub_device_t dev = NULL;
      grub_fs_t fs;

      grub_util_info ("opening %s", drives_names[0]);
      dev = grub_device_open (drives_names[0]);
      if (! dev)
	grub_util_error ("%s", grub_errmsg);
      
      fs = grub_fs_probe (dev);
      if (! fs)
	grub_util_error ("%s", grub_errmsg);

      if (print == PRINT_FS)
	{
	  printf ("%s", fs->name);
	  putchar (delim);
	}
      else if (print == PRINT_FS_UUID)
	{
	  char *uuid;
	  if (! fs->uuid)
	    grub_util_error (_("%s does not support UUIDs"), fs->name);

	  if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE)
	    grub_util_error ("%s", grub_errmsg);

	  printf ("%s", uuid);
	  putchar (delim);
	}
      else if (print == PRINT_FS_LABEL)
	{
	  char *label;
	  if (! fs->label)
	    grub_util_error (_("filesystem `%s' does not support labels"),
			     fs->name);

	  if (fs->label (dev, &label) != GRUB_ERR_NONE)
	    grub_util_error ("%s", grub_errmsg);

	  printf ("%s", label);
	  putchar (delim);
	}
      grub_device_close (dev);
      goto end;
    }

  for (curdrive = drives_names, curdev = device_names; *curdrive;
       curdrive++, curdev++)
    {
      grub_device_t dev = NULL;

      grub_util_info ("opening %s", *curdrive);
      dev = grub_device_open (*curdrive);
      if (! dev)
	grub_util_error ("%s", grub_errmsg);

      if (print == PRINT_HINT_STR)
	{
	  const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
	  const char *ofpath = osdev ? grub_util_devname_to_ofpath (osdev) : 0;
	  char *biosname, *bare, *efi;
	  const char *map;

	  if (ofpath)
	    {
	      char *tmp = xmalloc (strlen (ofpath) + sizeof ("ieee1275/"));
	      char *p;
	      p = grub_stpcpy (tmp, "ieee1275/");
	      strcpy (p, ofpath);
	      printf ("--hint-ieee1275='");
	      print_full_name (tmp, dev);
	      printf ("' ");
	      free (tmp);
	    }

	  biosname = guess_bios_drive (*curdev);
	  if (biosname)
	    {
	      printf ("--hint-bios=");
	      print_full_name (biosname, dev);
	      printf (" ");
	    }
	  free (biosname);

	  efi = guess_efi_drive (*curdev);
	  if (efi)
	    {
	      printf ("--hint-efi=");
	      print_full_name (efi, dev);
	      printf (" ");
	    }
	  free (efi);

	  bare = guess_baremetal_drive (*curdev);
	  if (bare)
	    {
	      printf ("--hint-baremetal=");
	      print_full_name (bare, dev);
	      printf (" ");
	    }
	  free (bare);

	  /* FIXME: Add ARC hint.  */

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      printf ("--hint='");
	      print_full_name (map, dev);
	      printf ("' ");
	    }
	  if (curdrive[1])
	    printf (" ");
	  else
	    printf ("\n");

	  grub_device_close (dev);
	  continue;
	}
      
      if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
	   || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
	   || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
	  && dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
	{
	  print_full_name (dev->disk->name, dev);
	  putchar (delim);
	  continue;
	}

      if (print == PRINT_COMPATIBILITY_HINT)
	{
	  const char *map;
	  char *biosname;
	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	      grub_device_close (dev);
	      /* Compatibility hint is one device only.  */
	      break;
	    }
	  biosname = guess_bios_drive (*curdev);
	  if (biosname)
	    {
	      print_full_name (biosname, dev);
	      putchar (delim);
	    }
	  free (biosname);
	  grub_device_close (dev);
	  /* Compatibility hint is one device only.  */
	  if (biosname)
	    break;
	  continue;
	}

      if (print == PRINT_BIOS_HINT)
	{
	  char *biosname;
	  biosname = guess_bios_drive (*curdev);
	  if (biosname)
	    {
	      print_full_name (biosname, dev);
	      putchar (delim);
	    }
	  free (biosname);
	  grub_device_close (dev);
	  continue;
	}
      if (print == PRINT_IEEE1275_HINT)
	{
	  const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
	  const char *ofpath = grub_util_devname_to_ofpath (osdev);
	  const char *map;

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	    }

	  if (ofpath)
	    {
	      char *tmp = xmalloc (strlen (ofpath) + sizeof ("ieee1275/"));
	      char *p;
	      p = grub_stpcpy (tmp, "ieee1275/");
	      strcpy (p, ofpath);
	      print_full_name (tmp, dev);
	      free (tmp);
	      putchar (delim);
	    }

	  grub_device_close (dev);
	  continue;
	}
      if (print == PRINT_EFI_HINT)
	{
	  char *biosname;
	  const char *map;
	  biosname = guess_efi_drive (*curdev);

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	    }
	  if (biosname)
	    {
	      print_full_name (biosname, dev);
	      putchar (delim);
	    }

	  free (biosname);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_BAREMETAL_HINT)
	{
	  char *biosname;
	  const char *map;

	  biosname = guess_baremetal_drive (*curdev);

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	    }
	  if (biosname)
	    {
	      print_full_name (biosname, dev);
	      putchar (delim);
	    }

	  free (biosname);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_ARC_HINT)
	{
	  const char *map;

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	    }

	  /* FIXME */
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_ABSTRACTION)
	{
	  probe_abstraction (dev->disk);
	  putchar (delim);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_CRYPTODISK_UUID)
	{
	  probe_cryptodisk_uuid (dev->disk);
	  putchar (delim);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_PARTMAP)
	{
	  /* Check if dev->disk itself is contained in a partmap.  */
	  probe_partmap (dev->disk);
	  putchar (delim);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_MSDOS_PARTTYPE)
	{
	  if (dev->disk->partition
	      && strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
	    printf ("%02x", dev->disk->partition->msdostype);

	  putchar (delim);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_GPT_PARTTYPE)
	{
          if (dev->disk->partition
	      && strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
            {
              struct grub_gpt_partentry gptdata;
              grub_partition_t p = dev->disk->partition;
              dev->disk->partition = dev->disk->partition->parent;

              if (grub_disk_read (dev->disk, p->offset, p->index,
                                  sizeof (gptdata), &gptdata) == 0)
                {
                  grub_gpt_part_type_t gpttype;
                  gpttype.data1 = grub_le_to_cpu32 (gptdata.type.data1);
                  gpttype.data2 = grub_le_to_cpu16 (gptdata.type.data2);
                  gpttype.data3 = grub_le_to_cpu16 (gptdata.type.data3);
                  grub_memcpy (gpttype.data4, gptdata.type.data4, 8);

                  grub_printf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                               gpttype.data1, gpttype.data2,
                               gpttype.data3, gpttype.data4[0], 
                               gpttype.data4[1], gpttype.data4[2],
                               gpttype.data4[3], gpttype.data4[4],
                               gpttype.data4[5], gpttype.data4[6],
                               gpttype.data4[7]);
                }
              dev->disk->partition = p;
            }
          putchar (delim);
          grub_device_close (dev);
          continue;
        }
    }

 end:
  for (curdrive = drives_names; *curdrive; curdrive++)
    free (*curdrive);
  free (drives_names);
}
Example #11
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;
  }
}
Example #12
0
static char *
adjust_file (const char *in, grub_size_t len)
{
  const char *comma, *ptr, *rest;
  char *ret, *outptr;
  int overhead = 0;
  int part = -1, subpart = -1;
  if (in[0] != '(')
    return grub_legacy_escape (in, len);
  for (ptr = in + 1; ptr < in + len && *ptr && *ptr != ')'
	 && *ptr != ','; ptr++)
    if (*ptr == '\'' || *ptr == '\\')
      overhead++;
  comma = ptr;
  if (*comma == ')' && comma - in == 3
      && in[1] == 'n' && in[2] == 'd')
    {
      rest = comma + 1;
      for (ptr = rest; ptr < in + len && *ptr; ptr++)
	if (*ptr == '\'' || *ptr == '\\')
	  overhead++;

      ret = grub_malloc (ptr - in + overhead + 15);
      if (!ret)
	return NULL;

      outptr = grub_stpcpy (ret, "(tftp)");;
      for (ptr = rest; ptr < in + len; ptr++)
	{
	  if (*ptr == '\'' || *ptr == '\\')
	    *outptr++ = '\\';

	  *outptr++ = *ptr;
	}
      *outptr = 0;
      return ret;
    }
  if (*comma != ',')
    return grub_legacy_escape (in, len);
  part = grub_strtoull (comma + 1, (char **) &rest, 0);
  if (rest[0] == ',' && rest[1] >= 'a' && rest[1] <= 'z')
    {
      subpart = rest[1] - 'a';
      rest += 2;
    }
  for (ptr = rest; ptr < in + len && *ptr; ptr++)
    if (*ptr == '\'' || *ptr == '\\')
      overhead++;

  /* 35 is enough for any 2 numbers.  */
  ret = grub_malloc (ptr - in + overhead + 35 + 5);
  if (!ret)
    return NULL;

  outptr = ret;
  for (ptr = in; ptr < in + len && ptr <= comma; ptr++)
    {
      if (*ptr == '\'' || *ptr == '\\')
	*outptr++ = '\\';
      
      *outptr++ = *ptr;
    }
  if (subpart != -1)
    grub_snprintf (outptr, 35, "%d,%d", part + 1, subpart + 1);
  else
    grub_snprintf (outptr, 35, "%d", part + 1);
  while (*outptr)
    outptr++;
  for (ptr = rest; ptr < in + len; ptr++)
    {
      if (*ptr == '\'' || *ptr == '\\')
	*outptr++ = '\\';
      
      *outptr++ = *ptr;
    }
  *outptr = 0;
  return ret;
}
Example #13
0
/* Run a menu entry.  */
static void
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
{
  grub_err_t err = GRUB_ERR_NONE;
  int errs_before;
  grub_menu_t menu = NULL;
  char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
  const char *ptr, *chosen, *def;
  grub_size_t sz = 0;

  if (entry->restricted)
    err = grub_auth_check_authentication (entry->users);

  if (err)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  errs_before = grub_err_printed_errors;

  chosen = grub_env_get ("chosen");
  def = grub_env_get ("default");

  if (entry->submenu)
    {
      grub_env_context_open ();
      menu = grub_zalloc (sizeof (*menu));
      if (! menu)
	return;
      grub_env_set_menu (menu);
      if (auto_boot)
	grub_env_set ("timeout", "0");
    }

  for (ptr = entry->id; *ptr; ptr++)
    sz += (*ptr == '>') ? 2 : 1;
  if (chosen)
    {
      oldchosen = grub_strdup (chosen);
      if (!oldchosen)
	grub_print_error ();
    }
  if (def)
    {
      olddefault = grub_strdup (def);
      if (!olddefault)
	grub_print_error ();
    }
  sz++;
  if (chosen)
    sz += grub_strlen (chosen);
  sz++;
  buf = grub_malloc (sz);
  if (!buf)
    grub_print_error ();
  else
    {
      optr = buf;
      if (chosen)
	{
	  optr = grub_stpcpy (optr, chosen);
	  *optr++ = '>';
	}
      for (ptr = entry->id; *ptr; ptr++)
	{
	  if (*ptr == '>')
	    *optr++ = '>';
	  *optr++ = *ptr;
	}
      *optr = 0;
      grub_env_set ("chosen", buf);
      grub_env_export ("chosen");
      grub_free (buf);
    }

  for (ptr = def; ptr && *ptr; ptr++)
    {
      if (ptr[0] == '>' && ptr[1] == '>')
	{
	  ptr++;
	  continue;
	}
      if (ptr[0] == '>')
	break;
    }

  if (ptr && ptr[0] && ptr[1])
    grub_env_set ("default", ptr + 1);
  else
    grub_env_unset ("default");

  grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);

  if (errs_before != grub_err_printed_errors)
    grub_wait_after_message ();

  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
    /* Implicit execution of boot, only if something is loaded.  */
    grub_command_execute ("boot", 0, 0);

  if (entry->submenu)
    {
      if (menu && menu->size)
	{
	  grub_show_menu (menu, 1, auto_boot);
	  grub_normal_free_menu (menu);
	}
      grub_env_context_close ();
    }
  if (oldchosen)
    grub_env_set ("chosen", oldchosen);
  else
    grub_env_unset ("chosen");
  if (olddefault)
    grub_env_set ("default", olddefault);
  else
    grub_env_unset ("default");
  grub_env_unset ("timeout");
}
Example #14
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;
}
Example #15
0
static grub_err_t
handle_symlink (struct grub_cpio_data *data,
		const char *fn, char **name,
		grub_uint32_t mode, int *restart)
{
  grub_size_t flen;
  char *target;
#ifndef MODE_USTAR
  grub_err_t err;
#endif
  char *ptr;
  char *lastslash;
  grub_size_t prefixlen;
  char *rest;
  grub_size_t size;

  *restart = 0;

  if ((mode & ATTR_TYPE) != ATTR_LNK)
    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++;

#ifdef MODE_USTAR
  size = grub_strlen (data->linkname);
#else
  size = data->size;
#endif
  if (size == 0)
    return GRUB_ERR_NONE;
  target = grub_malloc (size + grub_strlen (*name) + 2);
  if (!target)
    return grub_errno;

#ifdef MODE_USTAR
  grub_memcpy (target + prefixlen, data->linkname, size);
#else
  err = grub_disk_read (data->disk, 0, data->dofs, data->size, 
			target + prefixlen);
  if (err)
    return err;
#endif
  if (target[prefixlen] == '/')
    {
      grub_memmove (target, target + prefixlen, size);
      ptr = target + size;
      ptr = grub_stpcpy (ptr, rest);
      *ptr = 0;
      grub_dprintf ("cpio", "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] = '/';
    }
  ptr = target + prefixlen + size;
  ptr = grub_stpcpy (ptr, rest);
  *ptr = 0;
  grub_dprintf ("cpio", "symlink redirected %s to %s\n",
		*name, target);
  grub_free (*name);
  canonicalize (target);
  *name = target;
  *restart = 1;
  return GRUB_ERR_NONE;
}
Example #16
0
/* Load a font and add it to the beginning of the global font list.
   Returns 0 upon success, nonzero upon failure.  */
grub_font_t
grub_font_load (const char *filename)
{
  grub_file_t file = 0;
  struct font_file_section section;
  char magic[4];
  grub_font_t font = 0;

#if FONT_DEBUG >= 1
  grub_dprintf ("font", "add_font(%s)\n", filename);
#endif

  if (filename[0] == '(' || filename[0] == '/' || filename[0] == '+')
    file = grub_buffile_open (filename, 1024);
  else
    {
      const char *prefix = grub_env_get ("prefix");
      char *fullname, *ptr;
      if (!prefix)
	{
	  grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"),
		      "prefix");
	  goto fail;
	}
      fullname = grub_malloc (grub_strlen (prefix) + grub_strlen (filename) + 1
			      + sizeof ("/fonts/") + sizeof (".pf2"));
      if (!fullname)
	goto fail;
      ptr = grub_stpcpy (fullname, prefix);
      ptr = grub_stpcpy (ptr, "/fonts/");
      ptr = grub_stpcpy (ptr, filename);
      ptr = grub_stpcpy (ptr, ".pf2");
      *ptr = 0;
      file = grub_buffile_open (fullname, 1024);
      grub_free (fullname);
    }
  if (!file)
    goto fail;

#if FONT_DEBUG >= 3
  grub_dprintf ("font", "file opened\n");
#endif

  /* Read the FILE section.  It indicates the file format.  */
  if (open_section (file, &section) != 0)
    goto fail;

#if FONT_DEBUG >= 3
  grub_dprintf ("font", "opened FILE section\n");
#endif
  if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FILE,
		   sizeof (FONT_FORMAT_SECTION_NAMES_FILE) - 1) != 0)
    {
      grub_error (GRUB_ERR_BAD_FONT,
		  "font file format error: 1st section must be FILE");
      goto fail;
    }

#if FONT_DEBUG >= 3
  grub_dprintf ("font", "section name ok\n");
#endif
  if (section.length != 4)
    {
      grub_error (GRUB_ERR_BAD_FONT,
		  "font file format error (file type ID length is %d "
		  "but should be 4)", section.length);
      goto fail;
    }

#if FONT_DEBUG >= 3
  grub_dprintf ("font", "section length ok\n");
#endif
  /* Check the file format type code.  */
  if (grub_file_read (file, magic, 4) != 4)
    goto fail;

#if FONT_DEBUG >= 3
  grub_dprintf ("font", "read magic ok\n");
#endif

  if (grub_memcmp (magic, FONT_FORMAT_PFF2_MAGIC, 4) != 0)
    {
      grub_error (GRUB_ERR_BAD_FONT, "invalid font magic %x %x %x %x",
		  magic[0], magic[1], magic[2], magic[3]);
      goto fail;
    }

#if FONT_DEBUG >= 3
  grub_dprintf ("font", "compare magic ok\n");
#endif

  /* Allocate the font object.  */
  font = (grub_font_t) grub_zalloc (sizeof (struct grub_font));
  if (!font)
    goto fail;

  font_init (font);
  font->file = file;

#if FONT_DEBUG >= 3
  grub_dprintf ("font", "allocate font ok; loading font info\n");
#endif

  /* Load the font information.  */
  while (1)
    {
      if (open_section (file, &section) != 0)
	{
	  if (section.eof)
	    break;		/* Done reading the font file.  */
	  else
	    goto fail;
	}

#if FONT_DEBUG >= 2
      grub_dprintf ("font", "opened section %c%c%c%c ok\n",
		   section.name[0], section.name[1],
		   section.name[2], section.name[3]);
#endif

      if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME,
		       sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0)
	{
	  font->name = read_section_as_string (&section);
	  if (!font->name)
	    goto fail;
	}
      else if (grub_memcmp (section.name,
			    FONT_FORMAT_SECTION_NAMES_POINT_SIZE,
			    sizeof (FONT_FORMAT_SECTION_NAMES_POINT_SIZE) -
			    1) == 0)
	{
	  if (read_section_as_short (&section, &font->point_size) != 0)
	    goto fail;
	}
      else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_WEIGHT,
			    sizeof (FONT_FORMAT_SECTION_NAMES_WEIGHT) - 1)
	       == 0)
	{
	  char *wt;
	  wt = read_section_as_string (&section);
	  if (!wt)
	    continue;
	  /* Convert the weight string 'normal' or 'bold' into a number.  */
	  if (grub_strcmp (wt, "normal") == 0)
	    font->weight = FONT_WEIGHT_NORMAL;
	  else if (grub_strcmp (wt, "bold") == 0)
	    font->weight = FONT_WEIGHT_BOLD;
	  grub_free (wt);
	}
      else if (grub_memcmp (section.name,
			    FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH,
			    sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH)
			    - 1) == 0)
	{
	  if (read_section_as_short (&section, &font->max_char_width) != 0)
	    goto fail;
	}
      else if (grub_memcmp (section.name,
			    FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT,
			    sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT)
			    - 1) == 0)
	{
	  if (read_section_as_short (&section, &font->max_char_height) != 0)
	    goto fail;
	}
      else if (grub_memcmp (section.name,
			    FONT_FORMAT_SECTION_NAMES_ASCENT,
			    sizeof (FONT_FORMAT_SECTION_NAMES_ASCENT) - 1)
	       == 0)
	{
	  if (read_section_as_short (&section, &font->ascent) != 0)
	    goto fail;
	}
      else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DESCENT,
			    sizeof (FONT_FORMAT_SECTION_NAMES_DESCENT) - 1)
	       == 0)
	{
	  if (read_section_as_short (&section, &font->descent) != 0)
	    goto fail;
	}
      else if (grub_memcmp (section.name,
			    FONT_FORMAT_SECTION_NAMES_CHAR_INDEX,
			    sizeof (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) -
			    1) == 0)
	{
	  if (load_font_index (file, section.length, font) != 0)
	    goto fail;
	}
      else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DATA,
			    sizeof (FONT_FORMAT_SECTION_NAMES_DATA) - 1) == 0)
	{
	  /* When the DATA section marker is reached, we stop reading.  */
	  break;
	}
      else
	{
	  /* Unhandled section type, simply skip past it.  */
#if FONT_DEBUG >= 3
	  grub_dprintf ("font", "Unhandled section type, skipping.\n");
#endif
	  grub_off_t section_end = grub_file_tell (file) + section.length;
	  if ((int) grub_file_seek (file, section_end) == -1)
	    goto fail;
	}
    }

  if (!font->name)
    {
      grub_dprintf ("font", "Font has no name.\n");
      font->name = grub_strdup ("Unknown");
    }

#if FONT_DEBUG >= 1
  grub_dprintf ("font", "Loaded font `%s'.\n"
	       "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of characters=%d.\n",
	       font->name,
	       font->ascent, font->descent,
	       font->max_char_width, font->max_char_height, font->num_chars);
#endif

  if (font->max_char_width == 0
      || font->max_char_height == 0
      || font->num_chars == 0
      || font->char_index == 0 || font->ascent == 0 || font->descent == 0)
    {
      grub_error (GRUB_ERR_BAD_FONT,
		  "invalid font file: missing some required data");
      goto fail;
    }

  /* Add the font to the global font registry.  */
  if (register_font (font) != 0)
    goto fail;

  return font;

fail:
  if (file)
    grub_file_close (file);
  if (font)
    font->file = 0;

  free_font (font);
  return 0;
}
Example #17
0
static void
scan (void)
{
  auto int dev_iterate_real (const char *name, const char *path);

  int dev_iterate_real (const char *name, const char *path)
    {
      struct ofdisk_hash_ent *op;

      grub_dprintf ("disk", "disk name = %s, path = %s\n", name,
		    path);

      op = ofdisk_hash_find (path);
      if (!op)
	{
	  char *name_dup = grub_strdup (name);
	  char *can = grub_strdup (path);
	  if (!name_dup || !can)
	    {
	      grub_errno = GRUB_ERR_NONE;
	      grub_free (name_dup);
	      grub_free (can);
	      return 0;
	    }
	  op = ofdisk_hash_add (name_dup, can);
	}
      return 0;
    }

  auto int dev_iterate_alias (struct grub_ieee1275_devalias *alias);
  int dev_iterate_alias (struct grub_ieee1275_devalias *alias)
  {
    if (grub_strcmp (alias->type, "block") != 0)
      return 0;
    return dev_iterate_real (alias->name, alias->path);
  }

  auto int dev_iterate (struct grub_ieee1275_devalias *alias);
  int dev_iterate (struct grub_ieee1275_devalias *alias)
  {
    if (grub_strcmp (alias->type, "vscsi") == 0)
      {
	static grub_ieee1275_ihandle_t ihandle;
	struct set_color_args
	{
	  struct grub_ieee1275_common_hdr common;
	  grub_ieee1275_cell_t method;
	  grub_ieee1275_cell_t ihandle;
	  grub_ieee1275_cell_t catch_result;
	  grub_ieee1275_cell_t nentries;
	  grub_ieee1275_cell_t table;
	}
	args;
	char *buf, *bufptr;
	unsigned i;

	if (grub_ieee1275_open (alias->path, &ihandle))
	  return 0;
    
	INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
	args.method = (grub_ieee1275_cell_t) "vscsi-report-luns";
	args.ihandle = ihandle;
	args.table = 0;
	args.nentries = 0;

	if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
	  {
	    grub_ieee1275_close (ihandle);
	    return 0;
	  }

	buf = grub_malloc (grub_strlen (alias->path) + 32);
	if (!buf)
	  return 0;
	bufptr = grub_stpcpy (buf, alias->path);

	for (i = 0; i < args.nentries; i++)
	  {
	    grub_uint64_t *ptr;

	    ptr = *(grub_uint64_t **) (args.table + 4 + 8 * i);
	    while (*ptr)
	      {
		grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T, *ptr++);
		if (dev_iterate_real (buf, buf))
		  return 1;
	      }
	  }
	grub_ieee1275_close (ihandle);
	grub_free (buf);
	return 0;
      }

    if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS)
	&& grub_strcmp (alias->type, "block") == 0)
      return dev_iterate_real (alias->path, alias->path);

    return grub_children_iterate (alias->path, dev_iterate);
  }

  grub_devalias_iterate (dev_iterate_alias);
  grub_children_iterate ("/", dev_iterate);
}
Example #18
0
/* Eliminate "." and ".." path elements from PATH.  A new heap-allocated
   string is returned.  */
static char *
canonicalize_path (const char *path)
{
  int i;
  const char *p;
  char *newpath = 0;

  /* Count the path components in path.  */
  int components = 1;
  for (p = path; *p; p++)
    if (*p == '/')
      components++;

  char **path_array = grub_malloc (components * sizeof (*path_array));
  if (! path_array)
    return 0;

  /* Initialize array elements to NULL pointers; in case once of the
     allocations fails, the cleanup code can just call grub_free() for all
     pointers in the array.  */
  for (i = 0; i < components; i++)
    path_array[i] = 0;

  /* Parse the path into path_array.  */
  p = path;
  for (i = 0; i < components && p; i++)
    {
      /* Find the end of the path element.  */
      const char *end = grub_strchr (p, '/');
      if (!end)
        end = p + grub_strlen (p);

      /* Copy the element.  */
      path_array[i] = grub_new_substring (p, 0, end - p);
      if (! path_array[i])
        goto cleanup;

      /* Advance p to point to the start of the next element, or NULL.  */
      if (*end)
        p = end + 1;
      else
        p = 0;
    }

  /* Eliminate '.' and '..' elements from the path array.  */
  int newpath_length = 0;
  for (i = components - 1; i >= 0; --i)
    {
      if (! grub_strcmp (path_array[i], "."))
        {
          grub_free (path_array[i]);
          path_array[i] = 0;
        }
      else if (! grub_strcmp (path_array[i], "..")
               && i > 0)
        {
          /* Delete the '..' and the prior path element.  */
          grub_free (path_array[i]);
          path_array[i] = 0;
          --i;
          grub_free (path_array[i]);
          path_array[i] = 0;
        }
      else
        {
          newpath_length += grub_strlen (path_array[i]) + 1;
        }
    }

  /* Construct a new path string.  */
  newpath = grub_malloc (newpath_length + 1);
  if (! newpath)
    goto cleanup;

  newpath[0] = '\0';
  char *newpath_end = newpath;
  int first = 1;
  for (i = 0; i < components; i++)
    {
      char *element = path_array[i];
      if (element)
        {
          /* For all components but the first, prefix with a slash.  */
          if (! first)
            newpath_end = grub_stpcpy (newpath_end, "/");
          newpath_end = grub_stpcpy (newpath_end, element);
          first = 0;
        }
    }

cleanup:
  for (i = 0; i < components; i++)
    grub_free (path_array[i]);
  grub_free (path_array);

  return newpath;
}
Example #19
0
static void
dev_iterate (const struct grub_ieee1275_devalias *alias)
{
  if (grub_strcmp (alias->type, "vscsi") == 0)
    {
      static grub_ieee1275_ihandle_t ihandle;
      struct set_color_args
      {
	struct grub_ieee1275_common_hdr common;
	grub_ieee1275_cell_t method;
	grub_ieee1275_cell_t ihandle;
	grub_ieee1275_cell_t catch_result;
	grub_ieee1275_cell_t nentries;
	grub_ieee1275_cell_t table;
      }
      args;
      char *buf, *bufptr;
      unsigned i;

      if (grub_ieee1275_open (alias->path, &ihandle))
	return;
    
      INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
      args.method = (grub_ieee1275_cell_t) "vscsi-report-luns";
      args.ihandle = ihandle;
      args.table = 0;
      args.nentries = 0;

      if (IEEE1275_CALL_ENTRY_FN (&args) == -1 || args.catch_result)
	{
	  grub_ieee1275_close (ihandle);
	  return;
	}

      buf = grub_malloc (grub_strlen (alias->path) + 32);
      if (!buf)
	return;
      bufptr = grub_stpcpy (buf, alias->path);

      for (i = 0; i < args.nentries; i++)
	{
	  grub_uint64_t *ptr;

	  ptr = *(grub_uint64_t **) (args.table + 4 + 8 * i);
	  while (*ptr)
	    {
	      grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T, *ptr++);
	      dev_iterate_real (buf, buf);
	    }
	}
      grub_ieee1275_close (ihandle);
      grub_free (buf);
      return;
    }

  if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS)
      && grub_strcmp (alias->type, "block") == 0)
    {
      dev_iterate_real (alias->path, alias->path);
      return;
    }

  {
    struct grub_ieee1275_devalias child;

    FOR_IEEE1275_DEVCHILDREN(alias->path, child)
      dev_iterate (&child);
  }
}
Example #20
0
/* Create a new box.  If PIXMAPS_PREFIX and PIXMAPS_SUFFIX are both non-null,
   then an attempt is made to load the north, south, east, west, northwest,
   northeast, southeast, southwest, and center pixmaps.
   If either PIXMAPS_PREFIX or PIXMAPS_SUFFIX is 0, then no pixmaps are
   loaded, and the box has zero-width borders and is drawn transparent.  */
grub_gfxmenu_box_t
grub_gfxmenu_create_box (const char *pixmaps_prefix,
                         const char *pixmaps_suffix)
{
  unsigned i;
  grub_gfxmenu_box_t box;

  box = (grub_gfxmenu_box_t) grub_malloc (sizeof (*box));
  if (! box)
    return 0;

  box->content_width = 0;
  box->content_height = 0;
  box->raw_pixmaps =
    (struct grub_video_bitmap **)
    grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
  box->scaled_pixmaps =
    (struct grub_video_bitmap **)
    grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));

  /* Initialize all pixmap pointers to NULL so that proper destruction can
     be performed if an error is encountered partway through construction.  */
  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
      box->raw_pixmaps[i] = 0;
  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
      box->scaled_pixmaps[i] = 0;

  /* Load the pixmaps.  */
  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
    {
      if (pixmaps_prefix && pixmaps_suffix)
        {
          char *path;
          char *path_end;

          path = grub_malloc (grub_strlen (pixmaps_prefix)
                              + grub_strlen (box_pixmap_names[i])
                              + grub_strlen (pixmaps_suffix)
                              + 1);
          if (! path)
            goto fail_and_destroy;

          /* Construct the specific path for this pixmap.  */
          path_end = grub_stpcpy (path, pixmaps_prefix);
          path_end = grub_stpcpy (path_end, box_pixmap_names[i]);
          path_end = grub_stpcpy (path_end, pixmaps_suffix);

          grub_video_bitmap_load (&box->raw_pixmaps[i], path);
          grub_free (path);

          /* Ignore missing pixmaps.  */
          grub_errno = GRUB_ERR_NONE;
        }
    }

  box->draw = draw;
  box->set_content_size = set_content_size;
  box->get_left_pad = get_left_pad;
  box->get_top_pad = get_top_pad;
  box->get_right_pad = get_right_pad;
  box->get_bottom_pad = get_bottom_pad;
  box->destroy = destroy;
  return box;

fail_and_destroy:
  destroy (box);
  return 0;
}
Example #21
0
File: ofdisk.c Project: flihp/grub2
static void
dev_iterate (const struct grub_ieee1275_devalias *alias)
{
  if (grub_strcmp (alias->type, "vscsi") == 0)
    {
      static grub_ieee1275_ihandle_t ihandle;
      struct set_color_args
      {
	struct grub_ieee1275_common_hdr common;
	grub_ieee1275_cell_t method;
	grub_ieee1275_cell_t ihandle;
	grub_ieee1275_cell_t catch_result;
	grub_ieee1275_cell_t nentries;
	grub_ieee1275_cell_t table;
      }
      args;
      char *buf, *bufptr;
      unsigned i;

      if (grub_ieee1275_open (alias->path, &ihandle))
	return;

      /* This method doesn't need memory allocation for the table. Open
         firmware takes care of all memory management and the result table
         stays in memory and is never freed. */
      INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
      args.method = (grub_ieee1275_cell_t) "vscsi-report-luns";
      args.ihandle = ihandle;
      args.table = 0;
      args.nentries = 0;

      if (IEEE1275_CALL_ENTRY_FN (&args) == -1 || args.catch_result)
	{
	  grub_ieee1275_close (ihandle);
	  return;
	}

      buf = grub_malloc (grub_strlen (alias->path) + 32);
      if (!buf)
	return;
      bufptr = grub_stpcpy (buf, alias->path);

      for (i = 0; i < args.nentries; i++)
	{
	  grub_uint64_t *ptr;

	  ptr = *(grub_uint64_t **) (args.table + 4 + 8 * i);
	  while (*ptr)
	    {
	      grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T, *ptr++);
	      dev_iterate_real (buf, buf);
	    }
	}
      grub_ieee1275_close (ihandle);
      grub_free (buf);
      return;
    }
  else if (grub_strcmp (alias->type, "sas_ioa") == 0)
    {
      /* The method returns the number of disks and a table where
       * each ID is 64-bit long. Example of sas paths:
       *  /pci@80000002000001f/pci1014,034A@0/sas/disk@c05db70800
       *  /pci@80000002000001f/pci1014,034A@0/sas/disk@a05db70800
       *  /pci@80000002000001f/pci1014,034A@0/sas/disk@805db70800 */

      struct sas_children
        {
          struct grub_ieee1275_common_hdr common;
          grub_ieee1275_cell_t method;
          grub_ieee1275_cell_t ihandle;
          grub_ieee1275_cell_t max;
          grub_ieee1275_cell_t table;
          grub_ieee1275_cell_t catch_result;
          grub_ieee1275_cell_t nentries;
        }
      args;
      char *buf, *bufptr;
      unsigned i;
      grub_uint64_t *table;
      grub_uint16_t table_size;
      grub_ieee1275_ihandle_t ihandle;

      buf = grub_malloc (grub_strlen (alias->path) +
                         sizeof ("/disk@7766554433221100"));
      if (!buf)
        return;
      bufptr = grub_stpcpy (buf, alias->path);

      /* Power machines documentation specify 672 as maximum SAS disks in
         one system. Using a slightly larger value to be safe. */
      table_size = 768;
      table = grub_malloc (table_size * sizeof (grub_uint64_t));

      if (!table)
        {
          grub_free (buf);
          return;
        }

      if (grub_ieee1275_open (alias->path, &ihandle))
        {
          grub_free (buf);
          grub_free (table);
          return;
        }

      INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 2);
      args.method = (grub_ieee1275_cell_t) "get-sas-children";
      args.ihandle = ihandle;
      args.max = table_size;
      args.table = (grub_ieee1275_cell_t) table;
      args.catch_result = 0;
      args.nentries = 0;

      if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
        {
          grub_ieee1275_close (ihandle);
          grub_free (table);
          grub_free (buf);
          return;
        }

      for (i = 0; i < args.nentries; i++)
        {
          grub_snprintf (bufptr, sizeof ("/disk@7766554433221100"),
                        "/disk@%" PRIxGRUB_UINT64_T, table[i]);
          dev_iterate_real (buf, buf);
        }

      grub_ieee1275_close (ihandle);
      grub_free (table);
      grub_free (buf);
    }

  if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS)
      && grub_strcmp (alias->type, "block") == 0)
    {
      dev_iterate_real (alias->path, alias->path);
      return;
    }

  {
    struct grub_ieee1275_devalias child;

    FOR_IEEE1275_DEVCHILDREN(alias->path, child)
      dev_iterate (&child);
  }
}