/* 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; }
/* 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; }
/* 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; }
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; }
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; } }
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; }
/* 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; }
/* 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; }
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; }
/* 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; }
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; }
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; }
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 (); }