static void sqfs_ll_op_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) { sqfs_ll_i lli; sqfs_err sqerr; sqfs_name namebuf; sqfs_dir_entry entry; bool found; sqfs_inode inode; if (sqfs_ll_iget(req, &lli, parent)) return; if (!S_ISDIR(lli.inode.base.mode)) { fuse_reply_err(req, ENOTDIR); return; } sqfs_dentry_init(&entry, namebuf); sqerr = sqfs_dir_lookup(&lli.ll->fs, &lli.inode, name, strlen(name), &entry, &found); if (sqerr) { fuse_reply_err(req, EIO); return; } if (!found) { fuse_reply_err(req, ENOENT); return; } if (sqfs_inode_get(&lli.ll->fs, &inode, sqfs_dentry_inode(&entry))) { fuse_reply_err(req, ENOENT); } else { struct fuse_entry_param fentry; memset(&fentry, 0, sizeof(fentry)); if (sqfs_stat(&lli.ll->fs, &inode, &fentry.attr)) { fuse_reply_err(req, EIO); } else { fentry.attr_timeout = fentry.entry_timeout = SQFS_TIMEOUT; fentry.ino = lli.ll->ino_register(lli.ll, &entry); fentry.attr.st_ino = fentry.ino; fuse_reply_entry(req, &fentry); } } }
static sqfs_hl *sqfs_hl_open(const char *path, size_t offset) { sqfs_hl *hl; hl = malloc(sizeof(*hl)); if (!hl) { perror("Can't allocate memory"); } else { memset(hl, 0, sizeof(*hl)); if (sqfs_open_image(&hl->fs, path, offset) == SQFS_OK) { if (sqfs_inode_get(&hl->fs, &hl->root, sqfs_inode_root(&hl->fs))) fprintf(stderr, "Can't find the root of this filesystem!\n"); else return hl; sqfs_destroy(&hl->fs); } free(hl); } return NULL; }
int main(int argc, char *argv[]) { sqfs_err err = SQFS_OK; sqfs_traverse trv; sqfs fs; char *image; char *path_to_extract; char *prefix; char prefixed_path_to_extract[1024]; struct stat st; prefix = "squashfs-root/"; if (access(prefix, F_OK ) == -1 ) { if (mkdir(prefix, 0777) == -1) { perror("mkdir error"); exit(EXIT_FAILURE); } } if (argc != 3) usage(); image = argv[1]; path_to_extract = argv[2]; if ((err = sqfs_open_image(&fs, image, 0))) exit(ERR_OPEN); if ((err = sqfs_traverse_open(&trv, &fs, sqfs_inode_root(&fs)))) die("sqfs_traverse_open error"); while (sqfs_traverse_next(&trv, &err)) { if (!trv.dir_end) { if ((startsWith(path_to_extract, trv.path) != 0) || (strcmp("-a", path_to_extract) == 0)){ fprintf(stderr, "trv.path: %s\n", trv.path); fprintf(stderr, "sqfs_inode_id: %lu\n", trv.entry.inode); sqfs_inode inode; if (sqfs_inode_get(&fs, &inode, trv.entry.inode)) die("sqfs_inode_get error"); fprintf(stderr, "inode.base.inode_type: %i\n", inode.base.inode_type); fprintf(stderr, "inode.xtra.reg.file_size: %lu\n", inode.xtra.reg.file_size); strcpy(prefixed_path_to_extract, ""); strcat(strcat(prefixed_path_to_extract, prefix), trv.path); if (inode.base.inode_type == SQUASHFS_DIR_TYPE){ fprintf(stderr, "inode.xtra.dir.parent_inode: %ui\n", inode.xtra.dir.parent_inode); fprintf(stderr, "mkdir: %s/\n", prefixed_path_to_extract); if (access(prefixed_path_to_extract, F_OK ) == -1 ) { if (mkdir(prefixed_path_to_extract, 0777) == -1) { perror("mkdir error"); exit(1); } } } else if (inode.base.inode_type == SQUASHFS_REG_TYPE){ fprintf(stderr, "Extract to: %s\n", prefixed_path_to_extract); if (sqfs_stat(&fs, &inode, &st) != 0) die("sqfs_stat error"); printf("Permissions: "); printf( (S_ISDIR(st.st_mode)) ? "d" : "-"); printf( (st.st_mode & S_IRUSR) ? "r" : "-"); printf( (st.st_mode & S_IWUSR) ? "w" : "-"); printf( (st.st_mode & S_IXUSR) ? "x" : "-"); printf( (st.st_mode & S_IRGRP) ? "r" : "-"); printf( (st.st_mode & S_IWGRP) ? "w" : "-"); printf( (st.st_mode & S_IXGRP) ? "x" : "-"); printf( (st.st_mode & S_IROTH) ? "r" : "-"); printf( (st.st_mode & S_IWOTH) ? "w" : "-"); printf( (st.st_mode & S_IXOTH) ? "x" : "-"); printf("\n"); // Read the file in chunks off_t bytes_already_read = 0; sqfs_off_t bytes_at_a_time = 64*1024; FILE * f; f = fopen (prefixed_path_to_extract, "w+"); if (f == NULL) die("fopen error"); while (bytes_already_read < inode.xtra.reg.file_size) { char buf[bytes_at_a_time]; if (sqfs_read_range(&fs, &inode, (sqfs_off_t) bytes_already_read, &bytes_at_a_time, buf)) die("sqfs_read_range error"); // fwrite(buf, 1, bytes_at_a_time, stdout); fwrite(buf, 1, bytes_at_a_time, f); bytes_already_read = bytes_already_read + bytes_at_a_time; } fclose(f); chmod (prefixed_path_to_extract, st.st_mode); } else if (inode.base.inode_type == SQUASHFS_SYMLINK_TYPE){ size_t size = strlen(trv.path)+1; char buf[size]; int ret = sqfs_readlink(&fs, &inode, buf, &size); if (ret != 0) die("sqfs_readlink error"); fprintf(stderr, "Symlink: %s to %s \n", prefixed_path_to_extract, buf); unlink(prefixed_path_to_extract); ret = symlink(buf, prefixed_path_to_extract); if (ret != 0) die("symlink error"); } else { fprintf(stderr, "TODO: Implement inode.base.inode_type %i\n", inode.base.inode_type); } fprintf(stderr, "\n"); } } } if (err) die("sqfs_traverse_next error"); sqfs_traverse_close(&trv); sqfs_fd_close(fs.fd); return 0; }