Beispiel #1
0
/* Get the first entry number from the value of the environment variable NAME,
   which is a space-separated list of non-negative integers.  The entry number
   which is returned is stripped from the value of NAME.  If no entry number
   can be found, -1 is returned.  */
static int
get_and_remove_first_entry_number (const char *name)
{
  const char *val;
  char *tail;
  int entry;

  val = grub_env_get (name);
  if (! val)
    return -1;

  grub_error_push ();

  entry = (int) grub_strtoul (val, &tail, 0);

  if (grub_errno == GRUB_ERR_NONE)
    {
      /* Skip whitespace to find the next digit.  */
      while (*tail && grub_isspace (*tail))
	tail++;
      grub_env_set (name, tail);
    }
  else
    {
      grub_env_unset (name);
      grub_errno = GRUB_ERR_NONE;
      entry = -1;
    }

  grub_error_pop ();

  return entry;
}
Beispiel #2
0
/* Return the current timeout. If the variable "timeout" is not set or
   invalid, return -1.  */
int
grub_menu_get_timeout (void)
{
  const char *val;
  int timeout;

  val = grub_env_get ("timeout");
  if (! val)
    return -1;

  grub_error_push ();

  timeout = (int) grub_strtoul (val, 0, 0);

  /* If the value is invalid, unset the variable.  */
  if (grub_errno != GRUB_ERR_NONE)
    {
      grub_env_unset ("timeout");
      grub_errno = GRUB_ERR_NONE;
      timeout = -1;
    }

  grub_error_pop ();

  return timeout;
}
Beispiel #3
0
/* Get the entry number from the variable NAME.  */
static int
get_entry_number (grub_menu_t menu, const char *name)
{
  const char *val;
  int entry;

  val = grub_env_get (name);
  if (! val)
    return -1;

  grub_error_push ();

  entry = (int) grub_strtoul (val, 0, 0);

  if (grub_errno == GRUB_ERR_BAD_NUMBER)
    {
      /* See if the variable matches the title of a menu entry.  */
      grub_menu_entry_t e = menu->entry_list;
      int i;

      grub_errno = GRUB_ERR_NONE;

      for (i = 0; e; i++)
	{
	  if (menuentry_eq (e->title, val)
	      || menuentry_eq (e->id, val))
	    {
	      entry = i;
	      break;
	    }
	  e = e->next;
	}

      if (! e)
	entry = -1;
    }

  if (grub_errno != GRUB_ERR_NONE)
    {
      grub_errno = GRUB_ERR_NONE;
      entry = -1;
    }

  grub_error_pop ();

  return entry;
}
Beispiel #4
0
static grub_err_t
grub_mb2_tags_create (void)
{
  tag_create_t *creator;
  grub_err_t err;

  for (creator = grub_mb2_tag_creators; *creator != 0; creator++)
    {
      err = (*creator) ();
      if (err)
	goto error;
    }

  return GRUB_ERR_NONE;

error:
  grub_error_push ();
  grub_mb2_tags_free ();
  grub_error_pop ();
  return err;
}
Beispiel #5
0
void
grub_print_error (void)
{
  /* Print error messages in reverse order. First print active error message
     and then empty error stack.  */
  do
    {
      if (grub_errno != GRUB_ERR_NONE)
	{
	  grub_err_printf (_("error: %s.\n"), grub_errmsg);
	  grub_err_printed_errors++;
	}
    }
  while (grub_error_pop ());

  /* If there was an assert while using error stack, report about it.  */
  if (grub_error_stack_assert)
    {
      grub_err_printf ("assert: error stack overflow detected!\n");
      grub_error_stack_assert = 0;
    }
}
Beispiel #6
0
static grub_err_t
grub_mb2_tags_finish (void)
{
  struct multiboot_tag_start *start;
  grub_err_t err;

  /* Create the `end' tag.  */
  err = grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_END,
			   sizeof (struct multiboot_tag_end));
  if (err)
    goto error;

  /* We created the `start' tag first.  Update it now.  */
  start = (struct multiboot_tag_start *) grub_mb2_tags;
  start->size = grub_mb2_tags_pos - grub_mb2_tags;
  return GRUB_ERR_NONE;

error:
  grub_error_push ();
  grub_mb2_tags_free ();
  grub_error_pop ();
  return err;
}
Beispiel #7
0
/* Get a glyph corresponding to the codepoint CODE.  Always fill glyph
   information with something, even if no glyph is found.  */
int
grub_font_get_glyph (grub_uint32_t code,
                     grub_font_glyph_t glyph)
{
    struct font *font;
    grub_uint8_t bitmap[32];

    /* FIXME: It is necessary to cache glyphs!  */

restart:
    for (font = font_list; font; font = font->next)
    {
        grub_uint32_t offset;

        offset = find_glyph (font, code);
        if (offset)
        {
            grub_uint32_t w;
            int len;

            /* Make sure we can find glyphs for error messages.  Push active
               error message to error stack and reset error message.  */
            grub_error_push ();

            grub_file_seek (font->file, offset);
            if ((len = grub_file_read (font->file, (char *) &w, sizeof (w)))
                    != sizeof (w))
            {
                remove_font (font);
                goto restart;
            }

            w = grub_le_to_cpu32 (w);
            if (w != 1 && w != 2)
            {
                /* grub_error (GRUB_ERR_BAD_FONT, "invalid width"); */
                remove_font (font);
                goto restart;
            }

            if (grub_file_read (font->file, (char *) bitmap, w * 16)
                    != (grub_ssize_t) w * 16)
            {
                remove_font (font);
                goto restart;
            }

            /* Fill glyph with information.  */
            grub_memcpy (glyph->bitmap, bitmap, w * 16);

            glyph->char_width = w;
            glyph->width = glyph->char_width * 8;
            glyph->height = 16;
            glyph->baseline = (16 * 3) / 4;

            /* Restore old error message.  */
            grub_error_pop ();

            return 1;
        }
    }

    /* Uggh...  No font was found.  */
    fill_with_default_glyph (glyph);
    return 0;
}
Beispiel #8
0
/* Get a glyph for the Unicode character CODE in FONT.  The glyph is loaded
   from the font file if has not been loaded yet.
   Returns a pointer to the glyph if found, or 0 if it is not found.  */
static struct grub_font_glyph *
grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
{
  struct char_index_entry *index_entry;

  index_entry = find_glyph (font, code);
  if (index_entry)
    {
      struct grub_font_glyph *glyph = 0;
      grub_uint16_t width;
      grub_uint16_t height;
      grub_int16_t xoff;
      grub_int16_t yoff;
      grub_int16_t dwidth;
      int len;

      if (index_entry->glyph)
	/* Return cached glyph.  */
	return index_entry->glyph;

      if (!font->file)
	/* No open file, can't load any glyphs.  */
	return 0;

      /* Make sure we can find glyphs for error messages.  Push active
         error message to error stack and reset error message.  */
      grub_error_push ();

      grub_file_seek (font->file, index_entry->offset);

      /* Read the glyph width, height, and baseline.  */
      if (read_be_uint16 (font->file, &width) != 0
	  || read_be_uint16 (font->file, &height) != 0
	  || read_be_int16 (font->file, &xoff) != 0
	  || read_be_int16 (font->file, &yoff) != 0
	  || read_be_int16 (font->file, &dwidth) != 0)
	{
	  remove_font (font);
	  return 0;
	}

      len = (width * height + 7) / 8;
      glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
      if (!glyph)
	{
	  remove_font (font);
	  return 0;
	}

      glyph->font = font;
      glyph->width = width;
      glyph->height = height;
      glyph->offset_x = xoff;
      glyph->offset_y = yoff;
      glyph->device_width = dwidth;

      /* Don't try to read empty bitmaps (e.g., space characters).  */
      if (len != 0)
	{
	  if (grub_file_read (font->file, glyph->bitmap, len) != len)
	    {
	      remove_font (font);
	      return 0;
	    }
	}

      /* Restore old error message.  */
      grub_error_pop ();

      /* Cache the glyph.  */
      index_entry->glyph = glyph;

      return glyph;
    }

  return 0;
}
Beispiel #9
0
static const char *
grub_gettext_translate_real (struct grub_gettext_context *ctx,
			     const char *orig)
{
  grub_size_t current = 0;
  int i;
  const char *current_string;
  static int depth = 0;

  if (!ctx->grub_gettext_msg_list || !ctx->fd_mo)
    return NULL;

  /* Shouldn't happen. Just a precaution if our own code
     calls gettext somehow.  */
  if (depth > 2)
    return NULL;
  depth++;

  /* Make sure we can use grub_gettext_translate for error messages.  Push
     active error message to error stack and reset error message.  */
  grub_error_push ();

  for (i = ctx->grub_gettext_max_log; i >= 0; i--)
    {
      grub_size_t test;
      int cmp;

      test = current | (1 << i);
      if (test >= ctx->grub_gettext_max)
	continue;

      current_string = grub_gettext_getstring_from_position (ctx, test);

      if (!current_string)
	{
	  grub_errno = GRUB_ERR_NONE;
	  grub_error_pop ();
	  depth--;
	  return NULL;
	}

      /* Search by bisection.  */
      cmp = grub_strcmp (current_string, orig);
      if (cmp <= 0)
	current = test;
      if (cmp == 0)
	{
	  const char *ret = 0;
	  ret = grub_gettext_gettranslation_from_position (ctx, current);
	  if (!ret)
	    {
	      grub_errno = GRUB_ERR_NONE;
	      grub_error_pop ();
	      depth--;
	      return NULL;
	    }
	  grub_error_pop ();
	  depth--;
	  return ret;      
	}
    }

  if (current == 0 && ctx->grub_gettext_max != 0)
    {
      current_string = grub_gettext_getstring_from_position (ctx, 0);

      if (!current_string)
	{
	  grub_errno = GRUB_ERR_NONE;
	  grub_error_pop ();
	  depth--;
	  return NULL;
	}

      if (grub_strcmp (current_string, orig) == 0)
	{
	  const char *ret = 0;
	  ret = grub_gettext_gettranslation_from_position (ctx, current);
	  if (!ret)
	    {
	      grub_errno = GRUB_ERR_NONE;
	      grub_error_pop ();
	      depth--;
	      return NULL;
	    }
	  grub_error_pop ();
	  depth--;
	  return ret;      
	}
    }

  grub_error_pop ();
  depth--;
  return NULL;
}
Beispiel #10
0
/* FIXME: Previously 't' changed to text menu is it necessary?  */
static grub_err_t
grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
{
  grub_gfxmenu_view_t view = NULL;
  const char *theme_path;
  struct grub_menu_viewer *instance;
  grub_err_t err;
  struct grub_video_mode_info mode_info;

  theme_path = grub_env_get ("theme");
  if (! theme_path)
    {
      grub_error_push ();
      grub_gfxterm_fullscreen ();
      grub_error_pop ();
      return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no theme specified");
    }

  instance = grub_zalloc (sizeof (*instance));
  if (!instance)
    {
      grub_error_push ();
      grub_gfxterm_fullscreen ();
      grub_error_pop ();
      return grub_errno;
    }

  err = grub_video_get_info (&mode_info);
  if (err)
    {
      grub_error_push ();
      grub_gfxterm_fullscreen ();
      grub_error_pop ();
      return err;
    }

  if (!cached_view || grub_strcmp (cached_view->theme_path, theme_path) != 0
      || cached_view->screen.width != mode_info.width
      || cached_view->screen.height != mode_info.height)
    {
      grub_free (cached_view);
      /* Create the view.  */
      cached_view = grub_gfxmenu_view_new (theme_path, mode_info.width,
					   mode_info.height);
    }

  if (! cached_view)
    {
      grub_free (instance);
      grub_error_push ();
      grub_gfxterm_fullscreen ();
      grub_error_pop ();
      return grub_errno;
    }

  view = cached_view;

  view->double_repaint = (mode_info.mode_type
			  & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
    && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
  view->selected = entry;
  view->menu = menu;
  view->nested = nested;
  view->first_timeout = -1;

  grub_gfxmenu_view_draw (view);

  instance->data = view;
  instance->set_chosen_entry = grub_gfxmenu_set_chosen_entry;
  instance->fini = grub_gfxmenu_viewer_fini;
  instance->print_timeout = grub_gfxmenu_print_timeout;
  instance->clear_timeout = grub_gfxmenu_clear_timeout;

  grub_menu_register_viewer (instance);

  return GRUB_ERR_NONE;
}
Beispiel #11
0
static const char *
grub_gettext_translate (const char *orig)
{
  char *current_string;
  const char *ret;

  int min, max, current;
  int found = 0;

  struct grub_gettext_msg *cur;

  /* Make sure we can use grub_gettext_translate for error messages.  Push
     active error message to error stack and reset error message.  */
  grub_error_push ();

  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_gettext_msg_list),
			      orig);

  if (cur)
    {
      grub_error_pop ();
      return cur->translated;
    }

  if (fd_mo == 0)
    {
      grub_error_pop ();
      return orig;
    }

  min = 0;
  max = grub_gettext_max;

  current = (max + min) / 2;

  while (current != min && current != max && found == 0)
    {
      current_string = grub_gettext_getstring_from_position (current);

      /* Search by bisection.  */
      if (grub_strcmp (current_string, orig) < 0)
	{
	  grub_free (current_string);
	  min = current;
	}
      else if (grub_strcmp (current_string, orig) > 0)
	{
	  grub_free (current_string);
	  max = current;
	}
      else if (grub_strcmp (current_string, orig) == 0)
	{
	  grub_free (current_string);
	  found = 1;
	}
      current = (max + min) / 2;
    }

  ret = found ? grub_gettext_gettranslation_from_position (current) : orig;

  if (found)
    {
      cur = grub_zalloc (sizeof (*cur));

      if (cur)
	{
	  cur->name = grub_strdup (orig);
	  if (cur->name)
	    {
	      cur->translated = ret;
	      grub_list_push (GRUB_AS_LIST_P (&grub_gettext_msg_list),
			      GRUB_AS_LIST (cur));
	    }
	}
      else
	grub_errno = GRUB_ERR_NONE;
    }

  grub_error_pop ();
  return ret;
}
Beispiel #12
0
grub_fs_t
grub_fs_probe (grub_device_t device)
{
  grub_fs_t p;

  if (device->disk)
    {
      /* Make it sure not to have an infinite recursive calls.  */
      static int count = 0;

      for (p = grub_fs_list; p; p = p->next)
	{
	  grub_dprintf ("fs", "Detecting %s...\n", p->name);
	  (p->dir) (device, "/", dummy_func, 0);
	  if (grub_errno == GRUB_ERR_NONE)
	    return p;

	  grub_error_push ();
	  grub_dprintf ("fs", "%s detection failed.\n", p->name);
	  grub_error_pop ();

	  if (grub_errno != GRUB_ERR_BAD_FS)
	    return 0;

	  grub_errno = GRUB_ERR_NONE;
	}

      /* Let's load modules automatically.  */
      if (grub_fs_autoload_hook && count == 0)
	{
	  count++;

	  while (grub_fs_autoload_hook ())
	    {
	      p = grub_fs_list;

	      (p->dir) (device, "/", dummy_func, 0);
	      if (grub_errno == GRUB_ERR_NONE)
		{
		  count--;
		  return p;
		}

	      if (grub_errno != GRUB_ERR_BAD_FS)
		{
		  count--;
		  return 0;
		}

	      grub_errno = GRUB_ERR_NONE;
	    }

	  count--;
	}
    }
  else if (device->net->fs)
    return device->net->fs;

  grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem");
  return 0;
}
Beispiel #13
0
void
grub_module2 (int argc, char *argv[])
{
  grub_file_t file;
  grub_addr_t modaddr = 0;
  grub_ssize_t modsize = 0;
  grub_err_t err;

  if (argc == 0)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
      return;
    }

  if (argc == 1)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module type specified");
      return;
    }

  if (entry == 0)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT,
		  "You need to load the multiboot kernel first");
      return;
    }

  /* Load module data.  */
  file = grub_gzfile_open (argv[0], 1);
  if (! file)
    goto out;

  modsize = grub_file_size (file);
  err = grub_mb2_arch_module_alloc (modsize, &modaddr);
  if (err)
    goto out;

  grub_dprintf ("loader", "Loading module at 0x%x - 0x%x\n", modaddr,
		modaddr + modsize);
  if (grub_file_read (file, (char *) modaddr, modsize) != modsize)
    {
      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
      goto out;
    }

  /* Create the module tag.  */
  err = grub_mb2_tag_module_create (modaddr, modsize,
				   argv[1], MULTIBOOT2_TAG_MODULE,
				   argc-2, &argv[2]);
  if (err)
    goto out;

out:
  grub_error_push ();

  if (file)
    grub_file_close (file);

  if (modaddr)
    grub_mb2_arch_module_free (modaddr, modsize);

  grub_error_pop ();
}