/*---------------------------------------------------------------------------*/ static void copy_file_from_romfs_to_cfs(const char * from, const char * to) { static char buf[128]; cfs_offset_t filesize, read, pos; /* Format CFS */ cfs_coffee_format(); /* Open file for writing in CFS */ int cfs_fd = cfs_open(to, CFS_WRITE); /* Open file for reading in ROMFS */ int rom_fd = romfs_open(from, CFS_READ); /* Determine file size */ filesize = romfs_seek(rom_fd, 0, CFS_SEEK_END) - 1; /* Restore offset to start of file */ romfs_seek(rom_fd, 0, CFS_SEEK_SET); /* Copy file data from romfs to cfs in chunks of 128 bytes */ for (pos = 0; pos < filesize; pos += read) { read = romfs_read(rom_fd, buf, sizeof(buf)); cfs_write(cfs_fd, buf, read); } /* Close both files */ cfs_close(cfs_fd); romfs_close(rom_fd); }
static void do_uncompress(char *path, int fd, unsigned long offset, unsigned long size) { unsigned long curr = offset + 4 * ((size + blksize - 1) / blksize); do { unsigned long out = blksize; unsigned long next = u32_toggle_endianness(cramfs_is_big_endian, *(uint32_t *) romfs_read(offset)); if (next > end_data) end_data = next; offset += 4; if (curr == next) { if (opt_verbose > 1) printf(_(" hole at %ld (%zd)\n"), curr, blksize); if (size < blksize) out = size; memset(outbuffer, 0x00, out); } else { if (opt_verbose > 1) printf(_(" uncompressing block at %ld to %ld (%ld)\n"), curr, next, next - curr); out = uncompress_block(romfs_read(curr), next - curr); } if (size >= blksize) { if (out != blksize) errx(FSCK_EX_UNCORRECTED, _("non-block (%ld) bytes"), out); } else { if (out != size) errx(FSCK_EX_UNCORRECTED, _("non-size (%ld vs %ld) bytes"), out, size); } size -= out; if (*extract_dir != '\0') if (write(fd, outbuffer, out) < 0) err(FSCK_EX_ERROR, _("write failed: %s"), path); curr = next; } while (size); }
static void do_uncompress(char *path, int fd, unsigned long offset, unsigned long size) { unsigned long curr = offset + 4 * ((size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE); do { unsigned long out = PAGE_CACHE_SIZE; unsigned long next = *(u32 *) romfs_read(offset); if (next > end_data) { end_data = next; } offset += 4; if (curr == next) { if (opt_verbose > 1) { printf(" hole at %ld (%d)\n", curr, PAGE_CACHE_SIZE); } if (size < PAGE_CACHE_SIZE) out = size; memset(outbuffer, 0x00, out); } else { if (opt_verbose > 1) { printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr); } out = uncompress_block(romfs_read(curr), next - curr); } if (size >= PAGE_CACHE_SIZE) { if (out != PAGE_CACHE_SIZE) { die(FSCK_UNCORRECTED, 0, "non-block (%ld) bytes", out); } } else { if (out != size) { die(FSCK_UNCORRECTED, 0, "non-size (%ld vs %ld) bytes", out, size); } } size -= out; if (opt_extract) { if (write(fd, outbuffer, out) < 0) { die(FSCK_ERROR, 1, "write failed: %s", path); } } curr = next; } while (size); }
static void do_uncompress(int fd, unsigned long offset, unsigned long size) { unsigned long curr = offset + 4 * ((size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE); do { unsigned long out = PAGE_CACHE_SIZE; unsigned long next = *(unsigned long *) romfs_read(offset); if (next > end_data) { end_data = next; } offset += 4; if (curr == next) { if (opt_verbose > 1) { printf(" hole at %ld (%d)\n", curr, PAGE_CACHE_SIZE); } if (size < PAGE_CACHE_SIZE) out = size; memset(outbuffer, 0x00, out); } else { if (opt_verbose > 1) { printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr); } out = uncompress_block(romfs_read(curr), next - curr); } if (size >= PAGE_CACHE_SIZE) { if (out != PAGE_CACHE_SIZE) { fprintf(stderr, "%s: Non-block (%ld) bytes\n", filename, out); exit(4); } } else { if (out != size) { fprintf(stderr, "%s: Non-size (%ld vs %ld) bytes\n", filename, out, size); exit(4); } } size -= out; if (opt_extract) { write(fd, outbuffer, out); } curr = next; } while (size); }
static void do_symlink(char *path, struct cramfs_inode *i) { unsigned long offset = i->offset << 2; unsigned long curr = offset + 4; unsigned long next = *(u32 *) romfs_read(offset); unsigned long size; if (offset == 0) { die(FSCK_UNCORRECTED, 0, "symbolic link has zero offset"); } if (i->size == 0) { die(FSCK_UNCORRECTED, 0, "symbolic link has zero size"); } if (offset < start_data) { start_data = offset; } if (next > end_data) { end_data = next; } size = uncompress_block(romfs_read(curr), next - curr); if (size != i->size) { die(FSCK_UNCORRECTED, 0, "size error in symlink: %s", path); } outbuffer[size] = 0; if (opt_verbose) { char *str; asprintf(&str, "%s -> %s", path, outbuffer); print_node('l', i, str); if (opt_verbose > 1) { printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr); } free(str); } if (opt_extract) { if (symlink(outbuffer, path) < 0) { die(FSCK_ERROR, 1, "symlink failed: %s", path); } change_file_status(path, i); } }
static void do_directory(char *path, struct cramfs_inode *i) { int pathlen = strlen(path); int count = i->size; unsigned long offset = i->offset << 2; char *newpath = xmalloc(pathlen + 256); if (offset == 0 && count != 0) errx(FSCK_EX_UNCORRECTED, _("directory inode has zero offset and non-zero size: %s"), path); if (offset != 0 && offset < start_dir) start_dir = offset; /* TODO: Do we need to check end_dir for empty case? */ memcpy(newpath, path, pathlen); newpath[pathlen] = '/'; pathlen++; if (opt_verbose) print_node('d', i, path); if (*extract_dir != '\0') { if (mkdir(path, i->mode) < 0) err(FSCK_EX_ERROR, _("mkdir failed: %s"), path); change_file_status(path, i); } while (count > 0) { struct cramfs_inode *child = iget(offset); int size; int newlen = child->namelen << 2; size = sizeof(struct cramfs_inode) + newlen; count -= size; offset += sizeof(struct cramfs_inode); memcpy(newpath + pathlen, romfs_read(offset), newlen); newpath[pathlen + newlen] = 0; if (newlen == 0) errx(FSCK_EX_UNCORRECTED, _("filename length is zero")); if ((pathlen + newlen) - strlen(newpath) > 3) errx(FSCK_EX_UNCORRECTED, _("bad filename length")); expand_fs(newpath, child); offset += newlen; if (offset <= start_dir) errx(FSCK_EX_UNCORRECTED, _("bad inode offset")); if (offset > end_dir) end_dir = offset; iput(child); /* free(child) */ } free(newpath); }
static void do_symlink(char *path, struct cramfs_inode *i) { unsigned long offset = i->offset << 2; unsigned long curr = offset + 4; unsigned long next = u32_toggle_endianness(cramfs_is_big_endian, *(uint32_t *) romfs_read(offset)); unsigned long size; if (offset == 0) errx(FSCK_EX_UNCORRECTED, _("symbolic link has zero offset")); if (i->size == 0) errx(FSCK_EX_UNCORRECTED, _("symbolic link has zero size")); if (offset < start_data) start_data = offset; if (next > end_data) end_data = next; size = uncompress_block(romfs_read(curr), next - curr); if (size != i->size) errx(FSCK_EX_UNCORRECTED, _("size error in symlink: %s"), path); outbuffer[size] = 0; if (opt_verbose) { char *str; xasprintf(&str, "%s -> %s", path, outbuffer); print_node('l', i, str); if (opt_verbose > 1) printf(_(" uncompressing block at %ld to %ld (%ld)\n"), curr, next, next - curr); free(str); } if (*extract_dir != '\0') { if (symlink(outbuffer, path) < 0) err(FSCK_EX_ERROR, _("symlink failed: %s"), path); change_file_status(path, i); } }
static void do_symlink(char *path, struct cramfs_inode *i) { unsigned long offset = i->offset << 2; unsigned long curr = offset + 4; unsigned long next = *(unsigned long *) romfs_read(offset); unsigned long size; if (next > end_data) { end_data = next; } size = uncompress_block(romfs_read(curr), next - curr); if (size != i->size) { fprintf(stderr, "%s: size error in symlink `%s'\n", filename, path); exit(4); } outbuffer[size] = 0; if (opt_verbose) { char *str; str = malloc(strlen(outbuffer) + strlen(path) + 5); strcpy(str, path); strncat(str, " -> ", 4); strncat(str, outbuffer, size); print_node('l', i, str); if (opt_verbose > 1) { printf(" uncompressing block at %ld to %ld (%ld)\n", curr, next, next - curr); } } if (opt_extract) { symlink(outbuffer, path); change_file_status(path, i); } }
static int esp8266_lws_fops_read(struct lws *wsi, lws_filefd_type fd, unsigned long *amount, unsigned char *buf, unsigned long len) { struct esp8266_file *f = fd; size_t s; if ((long)buf & 3) { lwsl_err("misaligned buf\n"); return -1; } s = romfs_read(f->i, f->ofs, (uint32_t *)buf, len); *amount = s; f->ofs += s; return 0; }
static struct cramfs_inode *iget(unsigned int ino) { return cramfs_iget(romfs_read(ino)); }
static void expand_fs(int pathlen, char *path, struct cramfs_inode *inode) { if (S_ISDIR(inode->mode)) { int count = inode->size; unsigned long offset = inode->offset << 2; char *newpath = malloc(pathlen + 256); if (count > 0 && offset < start_inode) { start_inode = offset; } /* XXX - need to check end_inode for empty case? */ memcpy(newpath, path, pathlen); newpath[pathlen] = '/'; pathlen++; if (opt_verbose) { print_node('d', inode, path); } if (opt_extract) { mkdir(path, inode->mode); change_file_status(path, inode); } while (count > 0) { struct cramfs_inode *child = iget(offset); int size; int newlen = child->namelen << 2; size = sizeof(struct cramfs_inode) + newlen; count -= size; offset += sizeof(struct cramfs_inode); memcpy(newpath + pathlen, romfs_read(offset), newlen); newpath[pathlen + newlen] = 0; if ((pathlen + newlen) - strlen(newpath) > 3) { fprintf(stderr, "%s: invalid cramfs--bad path length\n", filename); exit(4); } expand_fs(strlen(newpath), newpath, child); offset += newlen; if (offset > end_inode) { end_inode = offset; } } return; } if (S_ISREG(inode->mode)) { int fd = 0; unsigned long offset = inode->offset << 2; if (offset > 0 && offset < start_data) { start_data = offset; } if (opt_verbose) { print_node('f', inode, path); } if (opt_extract) { fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, inode->mode); } if (inode->size) { do_uncompress(fd, offset, inode->size); } if (opt_extract) { close(fd); change_file_status(path, inode); } return; } if (S_ISLNK(inode->mode)) { unsigned long offset = inode->offset << 2; if (offset < start_data) { start_data = offset; } do_symlink(path, inode); return; } else { do_special_inode(path, inode); return; } }
uint32 RomfsStream::read(void *ptr, uint32 len) { return romfs_read((byte *)ptr, 1, len, (ROMFILE *)_handle); }