/* The command to add and remove loopback devices. */ static grub_err_t grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; grub_file_t file; struct grub_loopback *newdev; grub_err_t ret; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); /* Check if `-d' was used. */ if (state[0].set) return delete_loopback (args[0]); if (argc < 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); file = grub_file_open (args[1]); if (! file) return grub_errno; /* First try to replace the old device. */ for (newdev = loopback_list; newdev; newdev = newdev->next) if (grub_strcmp (newdev->devname, args[0]) == 0) break; if (newdev) { grub_file_close (newdev->file); newdev->file = file; return 0; } /* Unable to replace it, make a new entry. */ newdev = grub_malloc (sizeof (struct grub_loopback)); if (! newdev) goto fail; newdev->devname = grub_strdup (args[0]); if (! newdev->devname) { grub_free (newdev); goto fail; } newdev->file = file; /* Add the new entry to the list. */ newdev->next = loopback_list; loopback_list = newdev; return 0; fail: ret = grub_errno; grub_file_close (file); return ret; }
static grub_err_t grub_cmd_nthibr (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_uint8_t hibr_file_magic[4]; grub_file_t hibr_file = 0; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); hibr_file = grub_file_open (args[0]); if (!hibr_file) return grub_errno; /* Try to read magic number of 'hiberfil.sys' */ if (grub_file_read (hibr_file, hibr_file_magic, sizeof (hibr_file_magic)) != (grub_ssize_t) sizeof (hibr_file_magic)) { if (!grub_errno) grub_error (GRUB_ERR_TEST_FAILURE, "false"); goto exit; } if (!(grub_memcmp ("hibr", hibr_file_magic, sizeof (hibr_file_magic)) == 0 || grub_memcmp ("HIBR", hibr_file_magic, sizeof (hibr_file_magic)) == 0)) grub_error (GRUB_ERR_TEST_FAILURE, "false"); exit: grub_file_close (hibr_file); return grub_errno; }
/* Opens 'filename' with compression filters disabled. Optionally disables the PUBKEY filter (that insists upon properly signed files) as well. PUBKEY filter is restored before the function returns. */ static grub_file_t open_envblk_file (char *filename, enum grub_file_type type) { grub_file_t file; char *buf = 0; if (! filename) { const char *prefix; int len; prefix = grub_env_get ("prefix"); if (! prefix) { grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); return 0; } len = grub_strlen (prefix); buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG)); if (! buf) return 0; filename = buf; grub_strcpy (filename, prefix); filename[len] = '/'; grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG); } file = grub_file_open (filename, type); grub_free (buf); return file; }
grub_uitree_t grub_uitree_load_file (grub_uitree_t root, const char *name, int flags) { grub_uitree_t result = 0; grub_file_t file; int size; const char *prefix; file = grub_file_open (name); if (! file) return 0; prefix = grub_strrchr (name, '/'); if (! prefix) prefix = name; size = file->size; if (size) { char *buf; buf = grub_malloc (size); if (buf) { grub_file_read (file, buf, size); result = grub_uitree_load_buf (name, prefix - name, root, buf, size, flags); } grub_free (buf); } grub_file_close (file); return result; }
/* This is similar to grub_file_open. */ static grub_err_t grub_mofile_open (struct grub_gettext_context *ctx, const char *filename) { struct header head; grub_err_t err; grub_file_t fd; /* Using fd_mo and not another variable because it's needed for grub_gettext_get_info. */ fd = grub_file_open (filename); if (!fd) return grub_errno; err = grub_gettext_pread (fd, &head, sizeof (head), 0); if (err) { grub_file_close (fd); return err; } if (head.magic != grub_cpu_to_le32_compile_time (MO_MAGIC_NUMBER)) { grub_file_close (fd); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "mo: invalid mo magic in file: %s", filename); } if (head.version != 0) { grub_file_close (fd); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "mo: invalid mo version in file: %s", filename); } ctx->grub_gettext_offset_original = grub_le_to_cpu32 (head.offset_original); ctx->grub_gettext_offset_translation = grub_le_to_cpu32 (head.offset_translation); ctx->grub_gettext_max = grub_le_to_cpu32 (head.number_of_strings); for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log; ctx->grub_gettext_max_log++); ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max * sizeof (ctx->grub_gettext_msg_list[0])); if (!ctx->grub_gettext_msg_list) { grub_file_close (fd); return grub_errno; } ctx->fd_mo = fd; if (grub_gettext != grub_gettext_translate) { grub_gettext_original = grub_gettext; grub_gettext = grub_gettext_translate; } return 0; }
FILE *fopen(const char *path, const char *mode) { grub_errno = GRUB_ERR_NONE; if (grub_strcmp(mode, "r") != 0 && grub_strcmp(mode, "rb") != 0) { grub_printf("Internal error: Python attempted to open a file with unsupported mode \"%s\"\n", mode); return NULL; } return grub_file_open(path); }
static grub_err_t grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; int dos = 0; grub_file_t file; char buf[GRUB_DISK_SECTOR_SIZE]; grub_ssize_t size; int key = 0; if (state[0].set) dos = 1; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); file = grub_file_open (args[0]); if (! file) return grub_errno; while ((size = grub_file_read (file, buf, sizeof (buf))) > 0 && key != GRUB_TERM_ESC) { int i; for (i = 0; i < size; i++) { unsigned char c = buf[i]; if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') grub_printf ("%c", c); else if (dos && c == '\r' && i + 1 < size && buf[i + 1] == '\n') { grub_printf ("\n"); i++; } else { grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); grub_printf ("<%x>", (int) c); grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); } } while (grub_checkkey () >= 0 && (key = grub_getkey ()) != GRUB_TERM_ESC) ; } grub_xputs ("\n"); grub_refresh (); grub_file_close (file); return 0; }
grub_autolist_t grub_autolist_load (const char *name) { grub_autolist_t result = 0; const char *prefix; prefix = grub_env_get ("prefix"); if (prefix) { char *filename; filename = grub_xasprintf ("%s/%s", prefix, name); if (filename) { grub_file_t file; file = grub_file_open (filename); if (file) { char *buf = NULL; for (;; grub_free (buf)) { char *p; buf = grub_getline (file); if (! buf) break; if (! grub_isgraph (buf[0])) continue; p = grub_strchr (buf, ':'); if (! p) continue; *p = '\0'; while (*++p == ' ') ; insert_item (&result, buf, p); } grub_file_close (file); } grub_free (filename); } } return result; }
static grub_err_t grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_err_t err; grub_file_t file; grub_elf_t elf; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); grub_loader_unset (); file = grub_file_open (argv[0]); if (!file) return grub_errno; relocator = grub_relocator_new (); if (!relocator) { grub_file_close (file); return grub_errno; } elf = grub_elf_file (file, argv[0]); if (!elf) { grub_relocator_unload (relocator); relocator = 0; grub_file_close (file); } if (!grub_elf_is_elf32 (elf)) { grub_relocator_unload (relocator); relocator = 0; grub_elf_close (elf); } entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF; err = grub_elf32_load (elf, argv[0], grub_chain_elf32_hook, 0, 0); grub_elf_close (elf); if (err) return err; grub_loader_set (grub_chain_boot, grub_chain_unload, 0); return GRUB_ERR_NONE; }
grub_macho_t grub_macho_open (const char *name, int is_64bit) { grub_file_t file; grub_macho_t macho; file = grub_file_open (name); if (! file) return 0; macho = grub_macho_file (file, name, is_64bit); if (! macho) grub_file_close (file); return macho; }
grub_elf_t grub_elf_open (const char *name) { grub_file_t file; grub_elf_t elf; file = grub_file_open (name); if (! file) return 0; elf = grub_elf_file (file, name); if (! elf) grub_file_close (file); return elf; }
grub_file_t grub_buffile_open (const char *name, int size) { grub_file_t io, file; io = grub_file_open (name); if (! io) return 0; file = grub_bufio_open (io, size); if (! file) { grub_file_close (io); return 0; } return file; }
int stat(const char *path, struct stat *buf) { FILE *file; grub_errno = GRUB_ERR_NONE; file = grub_file_open(path); if (file) { buf->st_size = grub_file_size(file); grub_file_close(file); buf->st_mode = S_IFREG | 0777; } else { if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && is_directory(path)) { grub_errno = GRUB_ERR_NONE; buf->st_size = 0; buf->st_mode = S_IFDIR | 0777; } else { return -1; } } buf->st_mtime = 0; return 0; }
/* Opens 'filename' with compression filters disabled. Optionally disables the PUBKEY filter (that insists upon properly signed files) as well. PUBKEY filter is restored before the function returns. */ static grub_file_t open_envblk_file (char *filename, int untrusted) { grub_file_t file; char *buf = 0; if (! filename) { const char *prefix; int len; prefix = grub_env_get ("prefix"); if (! prefix) { grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); return 0; } len = grub_strlen (prefix); buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG)); if (! buf) return 0; filename = buf; grub_strcpy (filename, prefix); filename[len] = '/'; grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG); } /* The filters that are disabled will be re-enabled by the call to grub_file_open() after this particular file is opened. */ grub_file_filter_disable_compression (); if (untrusted) grub_file_filter_disable_pubkey (); file = grub_file_open (filename); grub_free (buf); return file; }
LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { LoadF lf; int status, readstatus; int c; int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ lf.extraline = 0; if (filename == NULL) { lua_pushliteral(L, "=stdin"); return errfile(L, "open", fnameindex); } else { lua_pushfstring(L, "@%s", filename); lf.f = grub_file_open(filename); if (lf.f == NULL) return errfile(L, "open", fnameindex); } c = grub_getc(lf.f); if (c == '#') { /* Unix exec. file? */ lf.extraline = 1; while ((c = grub_getc(lf.f)) != GRUB_EOF && c != '\n') ; /* skip first line */ if (c == '\n') c = grub_getc(lf.f); } if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ /* skip eventual `#!...' */ while ((c = grub_getc(lf.f)) != GRUB_EOF && c != LUA_SIGNATURE[0]) ; lf.extraline = 0; } lf.ungetc = c; status = lua_load(L, getF, &lf, lua_tostring(L, -1)); readstatus = grub_errno; grub_file_close(lf.f); /* close file (even in case of errors) */ if (readstatus) { lua_settop(L, fnameindex); /* ignore results from `lua_load' */ return errfile(L, "read", fnameindex); } lua_remove(L, fnameindex); return status; }
static grub_err_t grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file = 0; grub_ssize_t size; void *module = NULL; grub_addr_t target; grub_err_t err; int nounzip = 0; grub_uint64_t lowest_addr = 0; if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); if (grub_strcmp (argv[0], "--nounzip") == 0) { argv++; argc--; nounzip = 1; } if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); if (!grub_multiboot_relocator) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); if (nounzip) grub_file_filter_disable_compression (); file = grub_file_open (argv[0]); if (! file) return grub_errno; #ifndef GRUB_USE_MULTIBOOT2 lowest_addr = 0x100000; if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL) lowest_addr = ALIGN_UP (highest_load + 1048576, 4096); #endif size = grub_file_size (file); if (size) { grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, lowest_addr, (0xffffffff - size) + 1, size, MULTIBOOT_MOD_ALIGN, GRUB_RELOCATOR_PREFERENCE_NONE, 1); if (err) { grub_file_close (file); return err; } module = get_virtual_current_address (ch); target = get_physical_target_address (ch); } else { module = 0; target = 0; } err = grub_multiboot_add_module (target, size, argc - 1, argv + 1); if (err) { grub_file_close (file); return err; } if (size && grub_file_read (file, module, size) != size) { grub_file_close (file); if (!grub_errno) grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), argv[0]); return grub_errno; } /* Begin TCG Extension */ DEBUG_PRINT( ("measured multiboot module: %s \n", argv[0]) ); grub_TPM_measure_buffer( module, size, TPM_LOADER_MEASUREMENT_PCR ); /* End TCG Extension */ grub_file_close (file); return GRUB_ERR_NONE; }
static grub_err_t grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file = 0; grub_err_t err; grub_loader_unset (); highest_load = 0; #ifndef GRUB_USE_MULTIBOOT2 grub_multiboot_quirks = GRUB_MULTIBOOT_QUIRKS_NONE; int option_found = 0; do { option_found = 0; if (argc != 0 && grub_strcmp (argv[0], "--quirk-bad-kludge") == 0) { argc--; argv++; option_found = 1; grub_multiboot_quirks |= GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE; } if (argc != 0 && grub_strcmp (argv[0], "--quirk-modules-after-kernel") == 0) { argc--; argv++; option_found = 1; grub_multiboot_quirks |= GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL; } } while (option_found); #endif if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); file = grub_file_open (argv[0]); if (! file) return grub_errno; grub_dl_ref (my_mod); /* Skip filename. */ grub_multiboot_init_mbi (argc - 1, argv + 1); grub_relocator_unload (grub_multiboot_relocator); grub_multiboot_relocator = grub_relocator_new (); if (!grub_multiboot_relocator) goto fail; err = grub_multiboot_load (file, argv[0]); if (err) goto fail; grub_multiboot_set_bootdev (); grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); fail: if (file) grub_file_close (file); if (grub_errno != GRUB_ERR_NONE) { grub_relocator_unload (grub_multiboot_relocator); grub_multiboot_relocator = NULL; grub_dl_unref (my_mod); } else { /* Begin TCG Extension */ grub_TPM_measure_file( argv[0], TPM_LOADER_MEASUREMENT_PCR ); /* End TCG Extension */ } return grub_errno; }
static grub_err_t grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file = 0; struct linux_kernel_header lh; grub_ssize_t len, start, filelen; void *kernel = NULL; grub_dl_ref (my_mod); if (argc == 0) { grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); goto fail; } file = grub_file_open (argv[0]); if (! file) goto fail; filelen = grub_file_size (file); kernel = grub_malloc(filelen); if (!kernel) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); goto fail; } if (grub_file_read (file, kernel, filelen) != filelen) { grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); goto fail; } grub_tpm_measure (kernel, filelen, GRUB_KERNEL_PCR); if (! grub_linuxefi_secure_validate (kernel, filelen)) { grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]); grub_free (kernel); goto fail; } params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); if (! params) { grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); goto fail; } grub_memset (params, 0, 16384); grub_memcpy (&lh, kernel, sizeof (lh)); if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) { grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); goto fail; } if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) { grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); goto fail; } if (lh.version < grub_cpu_to_le16 (0x020b)) { grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); goto fail; } if (!lh.handover_offset) { grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); goto fail; } linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, BYTES_TO_PAGES(lh.cmdline_size + 1)); if (!linux_cmdline) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); goto fail; } grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); grub_create_loader_cmdline (argc, argv, linux_cmdline + sizeof (LINUX_IMAGE) - 1, lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); grub_pass_verity_hash(&lh, linux_cmdline); lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; handover_offset = lh.handover_offset; start = (lh.setup_sects + 1) * 512; len = grub_file_size(file) - start; kernel_mem = grub_efi_allocate_pages(lh.pref_address, BYTES_TO_PAGES(lh.init_size)); if (!kernel_mem) kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, BYTES_TO_PAGES(lh.init_size)); if (!kernel_mem) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); goto fail; } grub_memcpy (kernel_mem, (char *)kernel + start, len); grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); loaded=1; lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; grub_memcpy (params, &lh, 2 * 512); params->type_of_loader = 0x21; fail: if (file) grub_file_close (file); if (kernel) grub_free (kernel); if (grub_errno != GRUB_ERR_NONE) { grub_dl_unref (my_mod); loaded = 0; } if (linux_cmdline && !loaded) grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); if (kernel_mem && !loaded) grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); if (params && !loaded) grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); return grub_errno; }
static void read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) { static char buf[BUF_SIZE]; grub_file_t file; grub_off_t ofs, len; if ((pathname[0] == '-') && (pathname[1] == 0)) { grub_device_t dev; dev = grub_device_open (0); if ((! dev) || (! dev->disk)) grub_util_error (_("can\'t open device")); grub_util_info ("total sectors : %lld", (unsigned long long) dev->disk->total_sectors); if (! leng) leng = (dev->disk->total_sectors << GRUB_DISK_SECTOR_BITS) - skip; while (leng) { grub_size_t len; len = (leng > BUF_SIZE) ? BUF_SIZE : leng; if (grub_disk_read (dev->disk, 0, skip, len, buf)) grub_util_error (_("disk read fails at offset %lld, length %d"), skip, len); if (hook (skip, buf, len)) break; skip += len; leng -= len; } grub_device_close (dev); return; } grub_file_filter_disable_compression (); file = grub_file_open (pathname); if (!file) { grub_util_error (_("cannot open file %s:%s"), pathname, grub_errmsg); return; } grub_util_info ("file size : %lld", (unsigned long long) file->size); if (skip > file->size) { grub_util_error (_("invalid skip value %lld"), (unsigned long long) skip); return; } ofs = skip; len = file->size - skip; if ((leng) && (leng < len)) len = leng; file->offset = skip; while (len) { grub_ssize_t sz; sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len); if (sz < 0) { grub_util_error (_("read error at offset %llu: %s"), ofs, grub_errmsg); break; } if ((sz == 0) || (hook (ofs, buf, sz))) break; ofs += sz; len -= sz; } grub_file_close (file); }
/* Helper for grub_ls_list_files. */ static int print_files_long (const char *filename, const struct grub_dirhook_info *info, void *data) { struct grub_ls_list_files_ctx *ctx = data; if ((! ctx->all) && (filename[0] == '.')) return 0; if (! info->dir) { grub_file_t file; char *pathname; if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/') pathname = grub_xasprintf ("%s%s", ctx->dirname, filename); else pathname = grub_xasprintf ("%s/%s", ctx->dirname, filename); if (!pathname) return 1; /* XXX: For ext2fs symlinks are detected as files while they should be reported as directories. */ grub_file_filter_disable_compression (); file = grub_file_open (pathname); if (! file) { grub_errno = 0; grub_free (pathname); return 0; } if (! ctx->human) grub_printf ("%-12llu", (unsigned long long) file->size); else { grub_uint64_t fsize = file->size * 100ULL; grub_uint64_t fsz = file->size; int units = 0; char buf[20]; while (fsz / 1024) { fsize = (fsize + 512) / 1024; fsz /= 1024; units++; } if (units) { grub_uint64_t whole, fraction; whole = grub_divmod64 (fsize, 100, &fraction); grub_snprintf (buf, sizeof (buf), "%" PRIuGRUB_UINT64_T ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction, grub_human_sizes[units]); grub_printf ("%-12s", buf); } else grub_printf ("%-12llu", (unsigned long long) file->size); } grub_file_close (file); grub_free (pathname); } else grub_printf ("%-12s", _("DIR")); if (info->mtimeset) { struct grub_datetime datetime; grub_unixtime2datetime (info->mtime, &datetime); if (ctx->human) grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ", datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second, grub_get_weekday_name (&datetime)); else grub_printf (" %04d%02d%02d%02d%02d%02d ", datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second); } grub_printf ("%s%s\n", filename, info->dir ? "/" : ""); return 0; }
static grub_err_t grub_ls_list_files (char *dirname, int longlist, int all, int human) { char *device_name; grub_fs_t fs; const char *path; grub_device_t dev; device_name = grub_file_get_device_name (dirname); dev = grub_device_open (device_name); if (! dev) goto fail; fs = grub_fs_probe (dev); path = grub_strchr (dirname, ')'); if (! path) path = dirname; else path++; if (! path && ! device_name) { grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); goto fail; } if (! *path) { if (grub_errno == GRUB_ERR_UNKNOWN_FS) grub_errno = GRUB_ERR_NONE; grub_normal_print_device_info (device_name); } else if (fs) { struct grub_ls_list_files_ctx ctx = { .dirname = dirname, .all = all, .human = human }; if (longlist) (fs->dir) (dev, path, print_files_long, &ctx); else (fs->dir) (dev, path, print_files, &ctx); if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && path[grub_strlen (path) - 1] != '/') { /* PATH might be a regular file. */ char *p; grub_file_t file; struct grub_dirhook_info info; grub_errno = 0; grub_file_filter_disable_compression (); file = grub_file_open (dirname); if (! file) goto fail; grub_file_close (file); p = grub_strrchr (dirname, '/') + 1; dirname = grub_strndup (dirname, p - dirname); if (! dirname) goto fail; all = 1; grub_memset (&info, 0, sizeof (info)); if (longlist) print_files_long (p, &info, &ctx); else print_files (p, &info, &ctx); grub_free (dirname); } if (grub_errno == GRUB_ERR_NONE) grub_xputs ("\n"); grub_refresh (); } fail: if (dev) grub_device_close (dev); grub_free (device_name); return 0; }
static void grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) { grub_file_t file = 0; grub_uint16_t signature; grub_device_t dev; int drive = -1; void *part_addr = 0; grub_dl_ref (my_mod); file = grub_file_open (filename); if (! file) goto fail; /* Read the first block. */ if (grub_file_read (file, (void *) 0x7C00, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) { if (grub_errno == GRUB_ERR_NONE) grub_error (GRUB_ERR_BAD_OS, "too small"); goto fail; } /* Check the signature. */ signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2)); if (signature != grub_le_to_cpu16 (0xaa55) && ! (flags & GRUB_CHAINLOADER_FORCE)) { grub_error (GRUB_ERR_BAD_OS, "invalid signature"); goto fail; } grub_file_close (file); /* Obtain the partition table from the root device. */ drive = grub_get_root_biosnumber (); dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { grub_disk_t disk = dev->disk; if (disk) { grub_partition_t p = disk->partition; if (p && grub_strcmp (p->partmap->name, "msdos") == 0) { disk->partition = p->parent; grub_disk_read (disk, p->offset, 446, 64, (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR); part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR + (p->index << 4)); disk->partition = p; } } } if (dev) grub_device_close (dev); /* Ignore errors. Perhaps it's not fatal. */ grub_errno = GRUB_ERR_NONE; boot_drive = drive; boot_part_addr = part_addr; grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1); return; fail: if (file) grub_file_close (file); grub_dl_unref (my_mod); }
/* Set properties on the view based on settings from the specified theme file. */ grub_err_t grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) { grub_file_t file; struct parsebuf p; p.view = view; p.theme_dir = grub_get_dirname (theme_path); file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME); if (! file) { grub_free (p.theme_dir); return grub_errno; } p.len = grub_file_size (file); p.buf = grub_malloc (p.len); p.pos = 0; p.line_num = 1; p.col_num = 1; p.filename = theme_path; if (! p.buf) { grub_file_close (file); grub_free (p.theme_dir); return grub_errno; } if (grub_file_read (file, p.buf, p.len) != p.len) { grub_free (p.buf); grub_file_close (file); grub_free (p.theme_dir); return grub_errno; } if (view->canvas) view->canvas->component.ops->destroy (view->canvas); view->canvas = grub_gui_canvas_new (); if (!view->canvas) goto fail; ((grub_gui_component_t) view->canvas) ->ops->set_bounds ((grub_gui_component_t) view->canvas, &view->screen); while (has_more (&p)) { /* Skip comments (lines beginning with #). */ if (peek_char (&p) == '#') { advance_to_next_line (&p); continue; } /* Find the first non-whitespace character. */ skip_whitespace (&p); /* Handle the content. */ if (peek_char (&p) == '+') { /* Skip the '+'. */ read_char (&p); read_object (&p, view->canvas); } else { read_property (&p); } if (grub_errno != GRUB_ERR_NONE) goto fail; } /* Set the new theme path. */ grub_free (view->theme_path); view->theme_path = grub_strdup (theme_path); goto cleanup; fail: if (view->canvas) { view->canvas->component.ops->destroy (view->canvas); view->canvas = 0; } cleanup: grub_free (p.buf); grub_file_close (file); grub_free (p.theme_dir); return grub_errno; }
/* Helper for FUNC_NAME. */ static int iterate_device (const char *name, void *data) { struct search_ctx *ctx = data; int found = 0; /* Skip floppy drives when requested. */ if (ctx->no_floppy && name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') return 0; #ifdef DO_SEARCH_FS_UUID #define compare_fn grub_strcasecmp #else #define compare_fn grub_strcmp #endif #ifdef DO_SEARCH_FILE { char *buf; grub_file_t file; buf = grub_xasprintf ("(%s)%s", name, ctx->key); if (! buf) return 1; grub_file_filter_disable_compression (); file = grub_file_open (buf); if (file) { found = 1; grub_file_close (file); } grub_free (buf); } #elif defined(DO_SEARCH_PART_UUID) { grub_device_t dev; char *quid; dev = grub_device_open (name); if (dev) { if (grub_gpt_part_uuid (dev, &quid) == GRUB_ERR_NONE) { if (grub_strcasecmp (quid, ctx->key) == 0) found = 1; grub_free (quid); } grub_device_close (dev); } } #elif defined(DO_SEARCH_PART_LABEL) { grub_device_t dev; char *quid; dev = grub_device_open (name); if (dev) { if (grub_gpt_part_label (dev, &quid) == GRUB_ERR_NONE) { if (grub_strcmp (quid, ctx->key) == 0) found = 1; grub_free (quid); } grub_device_close (dev); } } #else { /* SEARCH_FS_UUID or SEARCH_LABEL */ grub_device_t dev; grub_fs_t fs; char *quid; dev = grub_device_open (name); if (dev) { fs = grub_fs_probe (dev); #ifdef DO_SEARCH_FS_UUID #define read_fn uuid #else #define read_fn label #endif if (fs && fs->read_fn) { fs->read_fn (dev, &quid); if (grub_errno == GRUB_ERR_NONE && quid) { if (compare_fn (quid, ctx->key) == 0) found = 1; grub_free (quid); } } grub_device_close (dev); } } #endif if (!ctx->is_cache && found && ctx->count == 0) { struct cache_entry *cache_ent; cache_ent = grub_malloc (sizeof (*cache_ent)); if (cache_ent) { cache_ent->key = grub_strdup (ctx->key); cache_ent->value = grub_strdup (name); if (cache_ent->value && cache_ent->key) { cache_ent->next = cache; cache = cache_ent; } else { grub_free (cache_ent->value); grub_free (cache_ent->key); grub_free (cache_ent); grub_errno = GRUB_ERR_NONE; } } else grub_errno = GRUB_ERR_NONE; } if (found) { ctx->count++; if (ctx->var) grub_env_set (ctx->var, name); else grub_printf (" %s", name); } grub_errno = GRUB_ERR_NONE; return (found && ctx->var); }
static grub_err_t grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t *files = 0; int i, nfiles = 0; grub_size_t size = 0; grub_uint8_t *ptr; if (argc == 0) { grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); goto fail; } if (!loaded) { grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); goto fail; } files = grub_zalloc (argc * sizeof (files[0])); if (!files) goto fail; for (i = 0; i < argc; i++) { grub_file_filter_disable_compression (); files[i] = grub_file_open (argv[i]); if (! files[i]) goto fail; nfiles++; size += ALIGN_UP (grub_file_size (files[i]), 4); } initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); if (!initrd_mem) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); goto fail; } params->ramdisk_size = size; params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem; ptr = initrd_mem; for (i = 0; i < nfiles; i++) { grub_ssize_t cursize = grub_file_size (files[i]); if (grub_file_read (files[i], ptr, cursize) != cursize) { if (!grub_errno) grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), argv[i]); goto fail; } grub_tpm_measure (ptr, cursize, GRUB_INITRD_PCR); ptr += cursize; grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); ptr += ALIGN_UP_OVERHEAD (cursize, 4); } params->ramdisk_size = size; fail: for (i = 0; i < nfiles; i++) grub_file_close (files[i]); grub_free (files); if (initrd_mem && grub_errno) grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size)); return grub_errno; }
static grub_err_t grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) { grub_file_t file = 0; grub_elf_t elf = 0; grub_err_t err; int type = -1, i; int ret = 0; grub_macho_t macho = 0; if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); for (i = OPT_TYPE_MIN; i <= OPT_TYPE_MAX; i++) if (ctxt->state[i].set) { if (type == -1) { type = i; continue; } return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple types specified"); } if (type == -1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no type specified"); file = grub_file_open (args[0]); if (!file) return grub_errno; switch (type) { case IS_BIOS_BOOTSECTOR: { grub_uint16_t sig; if (grub_file_size (file) != 512) break; if (grub_file_seek (file, 510) == (grub_size_t) -1) break; if (grub_file_read (file, &sig, 2) != 2) break; if (sig != grub_cpu_to_le16_compile_time (0xaa55)) break; ret = 1; break; } case IS_IA64_LINUX: { Elf64_Ehdr ehdr; if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) break; if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 || ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3 || ehdr.e_ident[EI_VERSION] != EV_CURRENT || ehdr.e_version != EV_CURRENT) break; if (ehdr.e_ident[EI_CLASS] != ELFCLASS64 || ehdr.e_ident[EI_DATA] != ELFDATA2LSB || ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_IA_64)) break; ret = 1; break; } case IS_SPARC64_LINUX: { Elf64_Ehdr ehdr; if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) break; if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 || ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3 || ehdr.e_ident[EI_VERSION] != EV_CURRENT || ehdr.e_version != EV_CURRENT) break; if (ehdr.e_ident[EI_CLASS] != ELFCLASS64 || ehdr.e_ident[EI_DATA] != ELFDATA2MSB) break; if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_SPARCV9) || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC)) break; ret = 1; break; } case IS_POWERPC_LINUX: { Elf32_Ehdr ehdr; if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) break; if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 || ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3 || ehdr.e_ident[EI_VERSION] != EV_CURRENT || ehdr.e_version != EV_CURRENT) break; if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB || (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_PPC) && ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_PPC64))) break; if (ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC) && ehdr.e_type != grub_cpu_to_be16_compile_time (ET_DYN)) break; ret = 1; break; } case IS_MIPS_LINUX: { Elf32_Ehdr ehdr; if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) break; if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 || ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3 || ehdr.e_ident[EI_VERSION] != EV_CURRENT || ehdr.e_version != EV_CURRENT) break; if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB || ehdr.e_machine != grub_cpu_to_be16_compile_time (EM_MIPS) || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC)) break; ret = 1; break; } case IS_X86_KNETBSD: case IS_X86_KNETBSD32: case IS_X86_KNETBSD64: { int is32, is64; elf = grub_elf_file (file, file->name); if (elf->ehdr.ehdr32.e_type != grub_cpu_to_le16_compile_time (ET_EXEC) || elf->ehdr.ehdr32.e_ident[EI_DATA] != ELFDATA2LSB) break; is32 = grub_elf_is_elf32 (elf); is64 = grub_elf_is_elf64 (elf); if (!is32 && !is64) break; if (!is32 && type == IS_X86_KNETBSD32) break; if (!is64 && type == IS_X86_KNETBSD64) break; if (is64) ret = grub_file_check_netbsd64 (elf); if (is32) ret = grub_file_check_netbsd32 (elf); break; } case IS_X86_KFREEBSD: case IS_X86_KFREEBSD32: case IS_X86_KFREEBSD64: { Elf32_Ehdr ehdr; int is32, is64; if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) break; if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 || ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3 || ehdr.e_ident[EI_VERSION] != EV_CURRENT || ehdr.e_version != EV_CURRENT) break; if (ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC) || ehdr.e_ident[EI_DATA] != ELFDATA2LSB) break; if (ehdr.e_ident[EI_OSABI] != ELFOSABI_FREEBSD) break; is32 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_386) && ehdr.e_ident[EI_CLASS] == ELFCLASS32); is64 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_X86_64) && ehdr.e_ident[EI_CLASS] == ELFCLASS64); if (!is32 && !is64) break; if (!is32 && (type == IS_X86_KFREEBSD32 || type == IS_X86_KNETBSD32)) break; if (!is64 && (type == IS_X86_KFREEBSD64 || type == IS_X86_KNETBSD64)) break; ret = 1; break; } case IS_MIPSEL_LINUX: { Elf32_Ehdr ehdr; if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) break; if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 || ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3 || ehdr.e_ident[EI_VERSION] != EV_CURRENT || ehdr.e_version != EV_CURRENT) break; if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_MIPS) || ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC)) break; ret = 1; break; } case IS_ARM_LINUX: { grub_uint32_t sig, sig_pi; if (grub_file_read (file, &sig_pi, 4) != 4) break; /* Raspberry pi. */ if (sig_pi == grub_cpu_to_le32_compile_time (0xea000006)) { ret = 1; break; } if (grub_file_seek (file, 0x24) == (grub_size_t) -1) break; if (grub_file_read (file, &sig, 4) != 4) break; if (sig == grub_cpu_to_le32_compile_time (0x016f2818)) { ret = 1; break; } break; } case IS_ARM64_LINUX: { grub_uint32_t sig; if (grub_file_seek (file, 0x38) == (grub_size_t) -1) break; if (grub_file_read (file, &sig, 4) != 4) break; if (sig == grub_cpu_to_le32_compile_time (0x644d5241)) { ret = 1; break; } break; } case IS_PAE_DOMU ... IS_DOM0: { struct grub_xen_file_info xen_inf; elf = grub_xen_file (file); if (!elf) break; err = grub_xen_get_info (elf, &xen_inf); if (err) break; /* Unfortuntely no way to check if kernel supports dom0. */ if (type == IS_DOM0) ret = 1; if (type == IS_PAE_DOMU) ret = (xen_inf.arch == GRUB_XEN_FILE_I386_PAE || xen_inf.arch == GRUB_XEN_FILE_I386_PAE_BIMODE); if (type == IS_64_DOMU) ret = (xen_inf.arch == GRUB_XEN_FILE_X86_64); break; } case IS_MULTIBOOT: case IS_MULTIBOOT2: { grub_uint32_t *buffer; grub_ssize_t len; grub_size_t search_size; grub_uint32_t *header; grub_uint32_t magic; grub_size_t step; if (type == IS_MULTIBOOT2) { search_size = 32768; magic = grub_cpu_to_le32_compile_time (0xe85250d6); step = 2; } else { search_size = 8192; magic = grub_cpu_to_le32_compile_time (0x1BADB002); step = 1; } buffer = grub_malloc (search_size); if (!buffer) break; len = grub_file_read (file, buffer, search_size); if (len < 32) { grub_free (buffer); break; } /* Look for the multiboot header in the buffer. The header should be at least 12 bytes and aligned on a 4-byte boundary. */ for (header = buffer; ((char *) header <= (char *) buffer + len - (type == IS_MULTIBOOT2 ? 16 : 12)) || (header = 0); header += step) { if (header[0] == magic && !(grub_le_to_cpu32 (header[0]) + grub_le_to_cpu32 (header[1]) + grub_le_to_cpu32 (header[2]) + (type == IS_MULTIBOOT2 ? grub_le_to_cpu32 (header[3]) : 0))) break; } if (header != 0) ret = 1; grub_free (buffer); break; } case IS_X86_LINUX32: case IS_X86_LINUX: { struct linux_kernel_header lh; if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) break; if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) break; if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) break; /* FIXME: some really old kernels (< 1.3.73) will fail this. */ if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE) || grub_le_to_cpu16 (lh.version) < 0x0200) break; if (type == IS_X86_LINUX) { ret = 1; break; } /* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and still not support 32-bit boot. */ if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE) || grub_le_to_cpu16 (lh.version) < 0x0203) break; if (!(lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL)) break; ret = 1; break; } case IS_HIBERNATED: { grub_uint8_t hibr_file_magic[4]; if (grub_file_read (file, &hibr_file_magic, sizeof (hibr_file_magic)) != sizeof (hibr_file_magic)) break; if (grub_memcmp ("hibr", hibr_file_magic, sizeof (hibr_file_magic)) == 0 || grub_memcmp ("HIBR", hibr_file_magic, sizeof (hibr_file_magic)) == 0) ret = 1; break; } case IS_XNU64: case IS_XNU32: { macho = grub_macho_open (args[0], (type == IS_XNU64)); if (!macho) break; /* FIXME: more checks? */ ret = 1; break; } case IS_XNU_HIBR: { struct grub_xnu_hibernate_header hibhead; if (grub_file_read (file, &hibhead, sizeof (hibhead)) != sizeof (hibhead)) break; if (hibhead.magic != grub_cpu_to_le32_compile_time (GRUB_XNU_HIBERNATE_MAGIC)) break; ret = 1; break; } case IS_32_EFI: case IS_64_EFI: case IS_IA_EFI: case IS_ARM64_EFI: case IS_ARM_EFI: { char signature[4]; grub_uint32_t pe_offset; struct grub_pe32_coff_header coff_head; if (grub_file_read (file, signature, 2) != 2) break; if (signature[0] != 'M' || signature[1] != 'Z') break; if ((grub_ssize_t) grub_file_seek (file, 0x3c) == -1) break; if (grub_file_read (file, &pe_offset, 4) != 4) break; if ((grub_ssize_t) grub_file_seek (file, grub_le_to_cpu32 (pe_offset)) == -1) break; if (grub_file_read (file, signature, 4) != 4) break; if (signature[0] != 'P' || signature[1] != 'E' || signature[2] != '\0' || signature[3] != '\0') break; if (grub_file_read (file, &coff_head, sizeof (coff_head)) != sizeof (coff_head)) break; if (type == IS_32_EFI && coff_head.machine != grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_I386)) break; if (type == IS_64_EFI && coff_head.machine != grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_X86_64)) break; if (type == IS_IA_EFI && coff_head.machine != grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_IA64)) break; if (type == IS_ARM64_EFI && coff_head.machine != grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARM64)) break; if (type == IS_ARM_EFI && coff_head.machine != grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARMTHUMB_MIXED)) break; if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI) { struct grub_pe64_optional_header o64; if (grub_file_read (file, &o64, sizeof (o64)) != sizeof (o64)) break; if (o64.magic != grub_cpu_to_le16_compile_time (GRUB_PE32_PE64_MAGIC)) break; if (o64.subsystem != grub_cpu_to_le16_compile_time (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION)) break; ret = 1; break; } if (type == IS_32_EFI || type == IS_ARM_EFI) { struct grub_pe32_optional_header o32; if (grub_file_read (file, &o32, sizeof (o32)) != sizeof (o32)) break; if (o32.magic != grub_cpu_to_le16_compile_time (GRUB_PE32_PE32_MAGIC)) break; if (o32.subsystem != grub_cpu_to_le16_compile_time (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION)) break; ret = 1; break; } break; } } if (elf) grub_elf_close (elf); else if (macho) grub_macho_close (macho); else if (file) grub_file_close (file); if (!ret && (grub_errno == GRUB_ERR_BAD_OS || grub_errno == GRUB_ERR_NONE)) /* TRANSLATORS: it's a standalone boolean value, opposite of "true". */ grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); return grub_errno; }
/* Read the file fs.lst for auto-loading. */ void read_fs_list (const char *prefix) { if (prefix) { char *filename; filename = grub_xasprintf ("%s/fs.lst", prefix); if (filename) { grub_file_t file; grub_fs_autoload_hook_t tmp_autoload_hook; /* This rules out the possibility that read_fs_list() is invoked recursively when we call grub_file_open() below. */ tmp_autoload_hook = grub_fs_autoload_hook; grub_fs_autoload_hook = NULL; file = grub_file_open (filename); if (file) { /* Override previous fs.lst. */ while (fs_module_list) { grub_named_list_t tmp; tmp = fs_module_list->next; grub_free (fs_module_list); fs_module_list = tmp; } while (1) { char *buf; char *p; char *q; grub_named_list_t fs_mod; buf = grub_getline (file); if (! buf) break; p = buf; q = buf + grub_strlen (buf) - 1; /* Ignore space. */ while (grub_isspace (*p)) p++; while (p < q && grub_isspace (*q)) *q-- = '\0'; /* If the line is empty, skip it. */ if (p >= q) continue; fs_mod = grub_malloc (sizeof (*fs_mod)); if (! fs_mod) continue; fs_mod->name = grub_strdup (p); if (! fs_mod->name) { grub_free (fs_mod); continue; } fs_mod->next = fs_module_list; fs_module_list = fs_mod; } grub_file_close (file); grub_fs_autoload_hook = tmp_autoload_hook; } grub_free (filename); } } /* Ignore errors. */ grub_errno = GRUB_ERR_NONE; /* Set the hook. */ grub_fs_autoload_hook = autoload_fs_module; }
static grub_err_t grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)), int argc, char **args_in) { char *uuid_root = 0, *uuid_prefix, *prefdev = 0; const char *prefix = 0; const char *path_prefix = 0; int mods_loaded = 0; grub_dl_t *mods; const char **args; int i; if (argc == 0) { argc = ARRAY_SIZE (modnames_def); args = modnames_def; } else args = (const char **) args_in; prefix = grub_env_get ("prefix"); if (! prefix) return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); if (prefix) path_prefix = (prefix[0] == '(') ? grub_strchr (prefix, ')') : NULL; if (path_prefix) path_prefix++; else path_prefix = prefix; mods = grub_malloc (argc * sizeof (mods[0])); if (!mods) return grub_errno; if (get_uuid (NULL, &uuid_root, 0)) return grub_errno; prefdev = grub_file_get_device_name (prefix); if (grub_errno) { grub_print_error (); prefdev = 0; } if (get_uuid (prefdev, &uuid_prefix, 0)) { grub_free (uuid_root); return grub_errno; } grub_dprintf ("nativedisk", "uuid_prefix = %s, uuid_root = %s\n", uuid_prefix, uuid_root); for (mods_loaded = 0; mods_loaded < argc; mods_loaded++) { char *filename; grub_dl_t mod; grub_file_t file = NULL; grub_ssize_t size; void *core = 0; mod = grub_dl_get (args[mods_loaded]); if (mod) { mods[mods_loaded] = 0; continue; } filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod", prefix, args[mods_loaded]); if (! filename) goto fail; file = grub_file_open (filename); grub_free (filename); if (! file) goto fail; size = grub_file_size (file); core = grub_malloc (size); if (! core) { grub_file_close (file); goto fail; } if (grub_file_read (file, core, size) != (grub_ssize_t) size) { grub_file_close (file); grub_free (core); goto fail; } grub_file_close (file); mods[mods_loaded] = grub_dl_load_core_noinit (core, size); if (! mods[mods_loaded]) goto fail; } for (i = 0; i < argc; i++) if (mods[i]) grub_dl_init (mods[i]); if (uuid_prefix || uuid_root) { struct search_ctx ctx; grub_fs_autoload_hook_t saved_autoload; /* No need to autoload FS since obviously we already have the necessary fs modules. */ saved_autoload = grub_fs_autoload_hook; grub_fs_autoload_hook = 0; ctx.root_uuid = uuid_root; ctx.prefix_uuid = uuid_prefix; ctx.prefix_path = path_prefix; ctx.prefix_found = !uuid_prefix; ctx.root_found = !uuid_root; /* FIXME: try to guess the correct values. */ grub_device_iterate (iterate_device, &ctx); grub_fs_autoload_hook = saved_autoload; } grub_free (uuid_root); grub_free (uuid_prefix); return GRUB_ERR_NONE; fail: grub_free (uuid_root); grub_free (uuid_prefix); for (i = 0; i < mods_loaded; i++) if (mods[i]) { mods[i]->fini = 0; grub_dl_unload (mods[i]); } return grub_errno; }
static grub_menu_t read_config_file (const char *config) { grub_file_t file; auto grub_err_t getline (char **line, int cont); grub_err_t getline (char **line, int cont __attribute__ ((unused))) { while (1) { char *buf; *line = buf = grub_file_getline (file); if (! buf) return grub_errno; if (buf[0] == '#') grub_free (*line); else break; } return GRUB_ERR_NONE; } grub_menu_t newmenu; newmenu = grub_env_get_menu (); if (! newmenu) { newmenu = grub_zalloc (sizeof (*newmenu)); if (! newmenu) return 0; grub_env_set_menu (newmenu); } /* Try to open the config file. */ file = grub_file_open (config); if (! file) return 0; while (1) { char *line; /* Print an error, if any. */ grub_print_error (); grub_errno = GRUB_ERR_NONE; if ((getline (&line, 0)) || (! line)) break; grub_normal_parse_line (line, getline); grub_free (line); } grub_file_close (file); return newmenu; }
/* Read the file crypto.lst for auto-loading. */ void read_crypto_list (const char *prefix) { char *filename; grub_file_t file; char *buf = NULL; if (!prefix) { grub_errno = GRUB_ERR_NONE; return; } filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/crypto.lst", prefix); if (!filename) { grub_errno = GRUB_ERR_NONE; return; } file = grub_file_open (filename); grub_free (filename); if (!file) { grub_errno = GRUB_ERR_NONE; return; } /* Override previous crypto.lst. */ grub_crypto_spec_free (); for (;; grub_free (buf)) { char *p, *name; struct load_spec *cur; buf = grub_file_getline (file); if (! buf) break; name = buf; while (grub_isspace (name[0])) name++; p = grub_strchr (name, ':'); if (! p) continue; *p = '\0'; p++; while (*p == ' ' || *p == '\t') p++; cur = grub_malloc (sizeof (*cur)); if (!cur) { grub_errno = GRUB_ERR_NONE; continue; } cur->name = grub_strdup (name); if (! name) { grub_errno = GRUB_ERR_NONE; grub_free (cur); continue; } cur->modname = grub_strdup (p); if (! cur->modname) { grub_errno = GRUB_ERR_NONE; grub_free (cur); grub_free (cur->name); continue; } cur->next = crypto_specs; crypto_specs = cur; } grub_file_close (file); grub_errno = GRUB_ERR_NONE; grub_crypto_autoload_hook = grub_crypto_autoload; }