static grub_err_t fetch_pixel (struct tga_data *data) { if (!data->uses_rle) { if (grub_file_read (data->file, &data->pixel[0], data->bpp) != data->bpp) return grub_errno; return GRUB_ERR_NONE; } if (!data->pktlen) { grub_uint8_t type; if (grub_file_read (data->file, &type, sizeof (type)) != sizeof(type)) return grub_errno; data->is_rle = !!(type & 0x80); data->pktlen = (type & 0x7f) + 1; if (data->is_rle && grub_file_read (data->file, &data->pixel[0], data->bpp) != data->bpp) return grub_errno; } if (!data->is_rle && grub_file_read (data->file, &data->pixel[0], data->bpp) != data->bpp) return grub_errno; data->pktlen--; return GRUB_ERR_NONE; }
static int test_gzip_header (grub_file_t file) { struct { grub_uint16_t magic; grub_uint8_t method; grub_uint8_t flags; grub_uint32_t timestamp; grub_uint8_t extra_flags; grub_uint8_t os_type; } hdr; grub_uint16_t extra_len; grub_uint32_t orig_len; grub_gzio_t gzio = file->data; if (grub_file_tell (gzio->file) != 0) grub_file_seek (gzio->file, 0); /* * This checks if the file is gzipped. If a problem occurs here * (other than a real error with the disk) then we don't think it * is a compressed file, and simply mark it as such. */ if (grub_file_read (gzio->file, &hdr, 10) != 10 || ((hdr.magic != GZIP_MAGIC) && (hdr.magic != OLD_GZIP_MAGIC))) return 0; /* * This does consistency checking on the header data. If a * problem occurs from here on, then we have corrupt or otherwise * bad data, and the error should be reported to the user. */ if (hdr.method != DEFLATED || (hdr.flags & UNSUPPORTED_FLAGS) || ((hdr.flags & EXTRA_FIELD) && (grub_file_read (gzio->file, &extra_len, 2) != 2 || eat_field (gzio->file, grub_le_to_cpu16 (extra_len)))) || ((hdr.flags & ORIG_NAME) && eat_field (gzio->file, -1)) || ((hdr.flags & COMMENT) && eat_field (gzio->file, -1))) return 0; gzio->data_offset = grub_file_tell (gzio->file); /* FIXME: don't do this on not easily seekable files. */ { grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4); if (grub_file_read (gzio->file, &orig_len, 4) != 4) return 0; /* FIXME: this does not handle files whose original size is over 4GB. But how can we know the real original size? */ file->size = grub_le_to_cpu32 (orig_len); } initialize_tables (gzio); return 1; }
/* Try to find out size of uncompressed data, * also do some footer sanity checks. */ static int test_footer (grub_file_t file) { grub_xzio_t xzio = file->data; grub_uint8_t footer[FOOTER_MAGIC_SIZE]; grub_uint32_t backsize; grub_uint8_t imarker; grub_uint64_t uncompressed_size_total = 0; grub_uint64_t uncompressed_size; grub_uint64_t records; grub_file_seek (xzio->file, xzio->file->size - FOOTER_MAGIC_SIZE); if (grub_file_read (xzio->file, footer, FOOTER_MAGIC_SIZE) != FOOTER_MAGIC_SIZE || grub_memcmp (footer, FOOTER_MAGIC, FOOTER_MAGIC_SIZE) != 0) goto ERROR; grub_file_seek (xzio->file, xzio->file->size - 8); if (grub_file_read (xzio->file, &backsize, sizeof (backsize)) != sizeof (backsize)) goto ERROR; /* Calculate real backward size. */ backsize = (grub_le_to_cpu32 (backsize) + 1) * 4; /* Set file to the beginning of stream index. */ grub_file_seek (xzio->file, xzio->file->size - XZ_STREAM_FOOTER_SIZE - backsize); /* Test index marker. */ if (grub_file_read (xzio->file, &imarker, sizeof (imarker)) != sizeof (imarker) && imarker != 0x00) goto ERROR; if (read_vli (xzio->file, &records) <= 0) goto ERROR; for (; records != 0; records--) { if (read_vli (xzio->file, &uncompressed_size) <= 0) /* Ignore unpadded. */ goto ERROR; if (read_vli (xzio->file, &uncompressed_size) <= 0) /* Uncompressed. */ goto ERROR; uncompressed_size_total += uncompressed_size; } file->size = uncompressed_size_total; grub_file_seek (xzio->file, STREAM_HEADER_SIZE); return 1; ERROR: grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "bad footer magic"); return 0; }
void grub_blocklist_convert (grub_file_t file) { struct read_blocklist_closure c; if ((file->fs == &grub_fs_blocklist) || (! file->device->disk) || (! file->size)) return; file->offset = 0; file->flags = 1; c.num = 0; c.blocks = 0; c.total_size = 0; c.part_start = grub_partition_get_start (file->device->disk->partition); file->read_hook = read_blocklist; file->closure = &c; grub_file_read (file, 0, file->size); file->read_hook = 0; if ((grub_errno) || (c.total_size != file->size)) { grub_errno = 0; grub_free (c.blocks); } else { if (file->fs->close) (file->fs->close) (file); file->fs = &grub_fs_blocklist; file->data = c.blocks; } file->offset = 0; }
/* Read block data into memory. File must be set to beginning of block data. * Can't be called on last block. */ static int read_block_data (struct grub_lzopio *lzopio) { lzopio->block.cdata = grub_malloc (lzopio->block.csize); if (!lzopio->block.cdata) return -1; if (grub_file_read (lzopio->file, lzopio->block.cdata, lzopio->block.csize) != (grub_ssize_t) lzopio->block.csize) return -1; if (lzopio->ccheck_fun) { grub_uint8_t computed_hash[GRUB_CRYPTO_MAX_MDLEN]; if (lzopio->ccheck_fun->mdlen > GRUB_CRYPTO_MAX_MDLEN) return -1; grub_crypto_hash (lzopio->ccheck_fun, computed_hash, lzopio->block.cdata, lzopio->block.csize); if (grub_memcmp (computed_hash, &lzopio->block.ccheck, sizeof (lzopio->block.ccheck)) != 0) return -1; } return 0; }
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; }
grub_err_t SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest) { grub_ssize_t read; if (! SUFFIX (grub_macho_contains_macho) (macho)) return grub_error (GRUB_ERR_BAD_OS, "couldn't read architecture-specific part"); if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1) { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, "invalid offset in program header"); } read = grub_file_read (macho->file, dest, macho->endXX - macho->offsetXX); if (read != (grub_ssize_t) (macho->endXX - macho->offsetXX)) { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, "couldn't read architecture-specific part"); } return GRUB_ERR_NONE; }
static grub_err_t tga_load_palette (struct tga_data *data) { grub_size_t len = grub_le_to_cpu32 (data->hdr.color_map_length) * 3; if (len > sizeof (data->palette)) len = sizeof (data->palette); if (grub_file_read (data->file, &data->palette, len) != (grub_ssize_t) len) return grub_errno; #ifndef GRUB_CPU_WORDS_BIGENDIAN { grub_size_t i; for (i = 0; 3 * i < len; i++) { grub_uint8_t t; t = data->palette[i][0]; data->palette[i][0] = data->palette[i][2]; data->palette[i][2] = t; } } #endif return GRUB_ERR_NONE; }
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; }
grub_elf_t grub_elf_file (grub_file_t file) { grub_elf_t elf; elf = grub_zalloc (sizeof (*elf)); if (! elf) return 0; elf->file = file; if (grub_file_seek (elf->file, 0) == (grub_off_t) -1) goto fail; if (grub_file_read (elf->file, &elf->ehdr, sizeof (elf->ehdr)) != sizeof (elf->ehdr)) { grub_error_push (); grub_error (GRUB_ERR_READ_ERROR, "cannot read ELF header"); goto fail; } if (grub_elf_check_header (elf)) goto fail; return elf; fail: grub_free (elf->phdrs); grub_free (elf); return 0; }
grub_err_t grub_elfXX_load_phdrs (grub_elf_t elf) { grub_ssize_t phdrs_size; if (elf->phdrs) return GRUB_ERR_NONE; phdrs_size = elf->ehdr.ehdrXX.e_phnum * elf->ehdr.ehdrXX.e_phentsize; grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n", (unsigned long long) elf->ehdr.ehdrXX.e_phoff, (unsigned long) phdrs_size); elf->phdrs = grub_malloc (phdrs_size); if (! elf->phdrs) return grub_errno; if ((grub_file_seek (elf->file, elf->ehdr.ehdrXX.e_phoff) == (grub_off_t) -1) || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size)) { if (!grub_errno) grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), elf->filename); return grub_errno; } return GRUB_ERR_NONE; }
static grub_err_t grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) { grub_file_t file = (grub_file_t) disk->data; grub_off_t pos; grub_file_seek (file, sector << GRUB_DISK_SECTOR_BITS); grub_file_read (file, buf, size << GRUB_DISK_SECTOR_BITS); if (grub_errno) return grub_errno; /* In case there is more data read than there is available, in case of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill the rest with zeros. */ pos = (sector + size) << GRUB_DISK_SECTOR_BITS; if (pos > file->size) { grub_size_t amount = pos - file->size; grub_memset (buf + (size << GRUB_DISK_SECTOR_BITS) - amount, 0, amount); } return 0; }
static const char *getF (lua_State *L, void *ud, size_t *size) { LoadF *lf = (LoadF *)ud; char *p; int s; (void)L; if (lf->extraline) { lf->extraline = 0; *size = 1; return "\n"; } s = sizeof (lf->buff); p = lf->buff; if (lf->ungetc >= 0) { lf->buff[0] = lf->ungetc; lf->ungetc = -1; s--; p++; } if (grub_eof(lf->f)) return NULL; s = grub_file_read(lf->f, p, s); if (s <= 0) return NULL; *size = s + (p - lf->buff); return (*size > 0) ? lf->buff : NULL; }
/* Function xz_dec_run() should consume header and ask for more (XZ_OK) * else file is corrupted (or options not supported) or not xz. */ static int test_header (grub_file_t file) { grub_xzio_t xzio = file->data; xzio->buf.in_size = grub_file_read (xzio->file, xzio->inbuf, STREAM_HEADER_SIZE); if (xzio->buf.in_size != STREAM_HEADER_SIZE) { grub_error (GRUB_ERR_BAD_FILE_TYPE, "no xz magic found"); return 0; } enum xz_ret ret = xz_dec_run (xzio->dec, &xzio->buf); if (ret == XZ_FORMAT_ERROR) { grub_error (GRUB_ERR_BAD_FILE_TYPE, "no xz magic found"); return 0; } if (ret != XZ_OK) { grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "not supported xz options"); return 0; } return 1; }
/* Load every loadable segment into memory specified by `_load_hook'. */ grub_err_t grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook, grub_addr_t *base, grub_size_t *size) { grub_addr_t load_base = (grub_addr_t) -1ULL; grub_size_t load_size = 0; grub_err_t err; auto int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook); int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook) { grub_elf32_load_hook_t load_hook = (grub_elf32_load_hook_t) hook; grub_addr_t load_addr; int do_load = 1; load_addr = phdr->p_paddr; if (load_hook && load_hook (phdr, &load_addr, &do_load)) return 1; if (! do_load) return 0; if (load_addr < load_base) load_base = load_addr; grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", (unsigned long long) load_addr, (unsigned long long) phdr->p_memsz); if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, "invalid offset in program header"); } if (phdr->p_filesz) { grub_ssize_t read; read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); if (read != (grub_ssize_t) phdr->p_filesz) { /* XXX How can we free memory from `load_hook'? */ grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, "couldn't read segment from file: " "wanted 0x%lx bytes; read 0x%lx bytes", phdr->p_filesz, read); } } if (phdr->p_filesz < phdr->p_memsz) grub_memset ((void *) (long) (load_addr + phdr->p_filesz), 0, phdr->p_memsz - phdr->p_filesz); load_size += phdr->p_memsz; return 0; }
/* Read a 16-bit big-endian integer from FILE, convert it to native byte order, and store it in *VALUE. Returns 0 on success, 1 on failure. */ static int read_be_uint16 (grub_file_t file, grub_uint16_t * value) { if (grub_file_read (file, value, 2) != 2) return 1; *value = grub_be_to_cpu16 (*value); return 0; }
static int grub_getc (grub_file_t file) { grub_uint8_t c = 0; return (grub_file_read (file, &c, 1) != 1) ? GRUB_EOF : c; return GRUB_EOF; }
static grub_ssize_t grub_offset_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_offset_file *data = file->data; if (grub_file_seek (data->parent, data->off + file->offset) == (grub_off_t) -1) return -1; return grub_file_read (data->parent, buf, len); }
static grub_err_t load_kernel (grub_file_t file, const char *filename, char *buffer, struct multiboot_header *header) { grub_err_t err; if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE) { err = grub_multiboot_load_elf (file, filename, buffer); if (err == GRUB_ERR_NONE) { return GRUB_ERR_NONE; } if (err == GRUB_ERR_UNKNOWN_OS && (header->flags & MULTIBOOT_AOUT_KLUDGE)) grub_errno = err = GRUB_ERR_NONE; } if (header->flags & MULTIBOOT_AOUT_KLUDGE) { int offset = ((char *) header - buffer - (header->header_addr - header->load_addr)); int load_size = ((header->load_end_addr == 0) ? file->size - offset : header->load_end_addr - header->load_addr); grub_size_t code_size; void *source; grub_relocator_chunk_t ch; if (header->bss_end_addr) code_size = (header->bss_end_addr - header->load_addr); else code_size = load_size; err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, &ch, header->load_addr, code_size); if (err) { grub_dprintf ("multiboot_loader", "Error loading aout kludge\n"); return err; } source = get_virtual_current_address (ch); if ((grub_file_seek (file, offset)) == (grub_off_t) -1) { return grub_errno; } grub_file_read (file, source, load_size); if (grub_errno) return grub_errno; if (header->bss_end_addr) grub_memset ((grub_uint8_t *) source + load_size, 0, header->bss_end_addr - header->load_addr - load_size); grub_multiboot_payload_eip = header->entry_addr; return GRUB_ERR_NONE; } return grub_multiboot_load_elf (file, filename, buffer); }
static grub_ssize_t grub_gettext_pread (grub_file_t file, void *buf, grub_size_t len, grub_off_t offset) { if (grub_file_seek (file, offset) == (grub_off_t) - 1) { return -1; } return grub_file_read (file, buf, len); }
static grub_uint32_t grub_png_get_dword (struct grub_png_data *data) { grub_uint32_t r; r = 0; grub_file_read (data->file, (char *) &r, sizeof (grub_uint32_t)); return grub_be_to_cpu32 (r); }
static inline grub_err_t read_headers (grub_file_t file, Elf_Ehdr *e, char **shdr) { if (grub_file_seek (file, 0) == (grub_off_t) -1) return grub_errno; if (grub_file_read (file, (char *) e, sizeof (*e)) != sizeof (*e)) { if (grub_errno) return grub_errno; else return grub_error (GRUB_ERR_BAD_OS, "file is too short"); } if (e->e_ident[EI_MAG0] != ELFMAG0 || e->e_ident[EI_MAG1] != ELFMAG1 || e->e_ident[EI_MAG2] != ELFMAG2 || e->e_ident[EI_MAG3] != ELFMAG3 || e->e_ident[EI_VERSION] != EV_CURRENT || e->e_version != EV_CURRENT) return grub_error (GRUB_ERR_BAD_OS, "invalid arch independent ELF magic"); if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS)) return grub_error (GRUB_ERR_BAD_OS, "invalid arch dependent ELF magic"); *shdr = grub_malloc (e->e_shnum * e->e_shentsize); if (! *shdr) return grub_errno; if (grub_file_seek (file, e->e_shoff) == (grub_off_t) -1) return grub_errno; if (grub_file_read (file, *shdr, e->e_shnum * e->e_shentsize) != e->e_shnum * e->e_shentsize) { if (grub_errno) return grub_errno; else return grub_error (GRUB_ERR_BAD_OS, "file is truncated"); } return GRUB_ERR_NONE; }
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; }
void SUFFIX (grub_macho_parse) (grub_macho_t macho) { grub_macho_header_t head; /* Is there any candidate at all? */ if (macho->offsetXX == -1) return; /* Read header and check magic*/ if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1 || grub_file_read (macho->file, &head, sizeof (head)) != sizeof(head)) { grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header"); macho->offsetXX = -1; return; } if (head.magic != GRUB_MACHO_MAGIC) { grub_error (GRUB_ERR_BAD_OS, "invalid Mach-O " XX "-bit header"); macho->offsetXX = -1; return; } /* Read commands. */ macho->ncmdsXX = head.ncmds; macho->cmdsizeXX = head.sizeofcmds; macho->cmdsXX = grub_malloc(macho->cmdsizeXX); if (! macho->cmdsXX) { grub_error (GRUB_ERR_OUT_OF_MEMORY, "not enough memory to read commands"); return; } if (grub_file_read (macho->file, macho->cmdsXX, (grub_size_t) macho->cmdsizeXX) != (grub_ssize_t) macho->cmdsizeXX) { grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header"); macho->offsetXX = -1; } }
/* Open the next section in the file. On success, the section name is stored in section->name and the length in section->length, and 0 is returned. On failure, 1 is returned and grub_errno is set appropriately with an error message. If 1 is returned due to being at the end of the file, then section->eof is set to 1; otherwise, section->eof is set to 0. */ static int open_section (grub_file_t file, struct font_file_section *section) { grub_ssize_t retval; grub_uint32_t raw_length; section->file = file; section->eof = 0; /* Read the FOURCC section name. */ retval = grub_file_read (file, section->name, 4); if (retval >= 0 && retval < 4) { /* EOF encountered. */ section->eof = 1; return 1; } else if (retval < 0) { /* Read error. */ return 1; } /* Read the big-endian 32-bit section length. */ retval = grub_file_read (file, &raw_length, 4); if (retval >= 0 && retval < 4) { /* EOF encountered. */ section->eof = 1; return 1; } else if (retval < 0) { /* Read error. */ return 1; } /* Convert byte-order and store in *length. */ section->length = grub_be_to_cpu32 (raw_length); return 0; }
grub_elf_t grub_xen_file (grub_file_t file) { grub_elf_t elf; struct linux_kernel_header lh; grub_file_t off_file; elf = grub_elf_file (file, file->name); if (elf) return elf; grub_errno = GRUB_ERR_NONE; if (grub_file_seek (file, 0) == (grub_off_t) -1) goto fail; if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) goto fail; if (lh.boot_flag != grub_cpu_to_le16 (0xaa55) || lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE) || grub_le_to_cpu16 (lh.version) < 0x0208) { grub_error (GRUB_ERR_BAD_OS, "version too old for xen boot"); return NULL; } if (lh.payload_length < 4) { grub_error (GRUB_ERR_BAD_OS, "payload too short"); return NULL; } grub_dprintf ("xen", "found bzimage payload 0x%llx-0x%llx\n", (unsigned long long) (lh.setup_sects + 1) * 512 + lh.payload_offset, (unsigned long long) lh.payload_length - 4); off_file = grub_file_offset_open (file, (lh.setup_sects + 1) * 512 + lh.payload_offset, lh.payload_length - 4); if (!off_file) goto fail; elf = grub_elf_file (off_file, file->name); if (elf) return elf; grub_file_offset_close (off_file); fail: grub_error (GRUB_ERR_BAD_OS, "not xen image"); return NULL; }
grub_err_t grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, char *argv[], void *target) { grub_uint8_t *ptr = target; int i; int newc = 0; struct dir *root = 0; grub_ssize_t cursize = 0; for (i = 0; i < initrd_ctx->nfiles; i++) { grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); ptr += ALIGN_UP_OVERHEAD (cursize, 4); if (initrd_ctx->components[i].newc_name) { ptr += insert_dir (initrd_ctx->components[i].newc_name, &root, ptr); ptr = make_header (ptr, initrd_ctx->components[i].newc_name, grub_strlen (initrd_ctx->components[i].newc_name), 0100777, initrd_ctx->components[i].size); newc = 1; } else if (newc) { ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0); free_dir (root); root = 0; newc = 0; } cursize = initrd_ctx->components[i].size; if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize) != cursize) { if (!grub_errno) grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), argv[i]); grub_initrd_close (initrd_ctx); return grub_errno; } ptr += cursize; } if (newc) ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0); free_dir (root); root = 0; return GRUB_ERR_NONE; }
static int get_byte (grub_file_t file) { grub_gzio_t gzio = file->data; if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset || gzio->inbuf_d == INBUFSIZ) { gzio->inbuf_d = 0; grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ); } return gzio->inbuf[gzio->inbuf_d++]; }
static inline grub_err_t load (grub_file_t file, void *where, grub_off_t off, grub_size_t size) { if (grub_file_seek (file, off) == (grub_off_t) -1) return grub_errno; if (grub_file_read (file, where, size) != (grub_ssize_t) size) { if (grub_errno) return grub_errno; else return grub_error (GRUB_ERR_BAD_OS, "file is truncated"); } return GRUB_ERR_NONE; }
static grub_ssize_t read_vli (grub_file_t file, grub_uint64_t * num) { grub_uint8_t buf[VLI_MAX_DIGITS]; grub_ssize_t read; grub_size_t dec; read = grub_file_read (file, buf, VLI_MAX_DIGITS); if (read < 0) return -1; dec = decode_vli (buf, read, num); grub_file_seek (file, file->offset - (read - dec)); return dec; }