diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-09-19 17:36:53 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-09-20 18:34:16 +0200 |
commit | 37a1176c3191cd722de613e26eda91518ca73751 (patch) | |
tree | 037aedf6f9de72203130102c05fe1bdf956275e0 /unpack/restore_fstree.c | |
parent | 5dcd267e9f0c5d93793e6d5e68279bd5dde5dff6 (diff) |
Remove fstree code from rdsquashfs
Use the directory reader from libsquashfs instead.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'unpack/restore_fstree.c')
-rw-r--r-- | unpack/restore_fstree.c | 199 |
1 files changed, 130 insertions, 69 deletions
diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c index 21bae3f..afa4abb 100644 --- a/unpack/restore_fstree.c +++ b/unpack/restore_fstree.c @@ -6,30 +6,30 @@ */ #include "rdsquashfs.h" -static int create_node(tree_node_t *n, int flags) +static int create_node(const sqfs_tree_node_t *n, int flags) { - tree_node_t *c; - int fd, ret; + const sqfs_tree_node_t *c; char *name; + int fd; if (!(flags & UNPACK_QUIET)) { - name = fstree_get_path(n); + name = sqfs_tree_node_get_path(n); printf("creating %s\n", name); free(name); } - switch (n->mode & S_IFMT) { + switch (n->inode->base.mode & S_IFMT) { case S_IFDIR: - if (mkdir(n->name, 0755) && errno != EEXIST) { + if (mkdir((const char *)n->name, 0755) && errno != EEXIST) { fprintf(stderr, "mkdir %s: %s\n", n->name, strerror(errno)); return -1; } - if (pushd(n->name)) + if (pushd((const char *)n->name)) return -1; - for (c = n->data.dir->children; c != NULL; c = c->next) { + for (c = n->children; c != NULL; c = c->next) { if (create_node(c, flags)) return -1; } @@ -38,31 +38,44 @@ static int create_node(tree_node_t *n, int flags) return -1; break; case S_IFLNK: - if (symlink(n->data.slink_target, n->name)) { + if (symlink(n->inode->slink_target, (const char *)n->name)) { fprintf(stderr, "ln -s %s %s: %s\n", - n->data.slink_target, n->name, + n->inode->slink_target, n->name, strerror(errno)); return -1; } break; case S_IFSOCK: case S_IFIFO: - if (mknod(n->name, (n->mode & S_IFMT) | 0700, 0)) { + if (mknod((const char *)n->name, + (n->inode->base.mode & S_IFMT) | 0700, 0)) { fprintf(stderr, "creating %s: %s\n", n->name, strerror(errno)); return -1; } break; case S_IFBLK: - case S_IFCHR: - if (mknod(n->name, n->mode & S_IFMT, n->data.devno)) { + case S_IFCHR: { + uint32_t devno; + + if (n->inode->base.type == SQFS_INODE_EXT_BDEV || + n->inode->base.type == SQFS_INODE_EXT_CDEV) { + devno = n->inode->data.dev_ext.devno; + } else { + devno = n->inode->data.dev.devno; + } + + if (mknod((const char *)n->name, n->inode->base.mode & S_IFMT, + devno)) { fprintf(stderr, "creating device %s: %s\n", n->name, strerror(errno)); return -1; } break; + } case S_IFREG: - fd = open(n->name, O_WRONLY | O_CREAT | O_EXCL, 0600); + fd = open((const char *)n->name, O_WRONLY | O_CREAT | O_EXCL, + 0600); if (fd < 0) { fprintf(stderr, "creating %s: %s\n", n->name, strerror(errno)); @@ -70,38 +83,99 @@ static int create_node(tree_node_t *n, int flags) } close(fd); + break; + default: + break; + } - if (n->parent != NULL) { - n->data.file->input_file = fstree_get_path(n); - } else { - n->data.file->input_file = strdup(n->name); + return 0; +} + +#ifdef HAVE_SYS_XATTR_H +static int set_xattr(sqfs_xattr_reader_t *xattr, const sqfs_tree_node_t *n) +{ + sqfs_xattr_value_t *value; + sqfs_xattr_entry_t *key; + sqfs_xattr_id_t desc; + uint32_t index; + size_t i; + int ret; + + switch (n->inode->base.type) { + case SQFS_INODE_EXT_DIR: + index = n->inode->data.dir_ext.xattr_idx; + break; + case SQFS_INODE_EXT_FILE: + index = n->inode->data.file_ext.xattr_idx; + break; + case SQFS_INODE_EXT_SLINK: + index = n->inode->data.slink_ext.xattr_idx; + break; + case SQFS_INODE_EXT_BDEV: + case SQFS_INODE_EXT_CDEV: + index = n->inode->data.dev_ext.xattr_idx; + break; + case SQFS_INODE_EXT_FIFO: + case SQFS_INODE_EXT_SOCKET: + index = n->inode->data.ipc_ext.xattr_idx; + break; + default: + return 0; + } + + if (index == 0xFFFFFFFF) + return 0; + + if (sqfs_xattr_reader_get_desc(xattr, index, &desc)) { + fputs("Error resolving xattr index\n", stderr); + return -1; + } + + if (sqfs_xattr_reader_seek_kv(xattr, &desc)) { + fputs("Error locating xattr key-value pairs\n", stderr); + return -1; + } + + for (i = 0; i < desc.count; ++i) { + if (sqfs_xattr_reader_read_key(xattr, &key)) { + fputs("Error reading xattr key\n", stderr); + return -1; } - if (n->data.file->input_file == NULL) { - perror("restoring file path"); + if (sqfs_xattr_reader_read_value(xattr, key, &value)) { + fputs("Error reading xattr value\n", stderr); + free(key); return -1; } - ret = canonicalize_name(n->data.file->input_file); - assert(ret == 0); - break; - default: - break; + ret = lsetxattr((const char *)n->name, (const char *)key->key, + value->value, value->size, 0); + if (ret) { + fprintf(stderr, "setting xattr '%s' on %s: %s\n", + key->key, n->name, strerror(errno)); + } + + free(key); + free(value); + if (ret) + return -1; } return 0; } +#endif -static int set_attribs(fstree_t *fs, tree_node_t *n, int flags) +static int set_attribs(sqfs_xattr_reader_t *xattr, + const sqfs_tree_node_t *n, int flags) { - tree_node_t *c; + const sqfs_tree_node_t *c; - if (S_ISDIR(n->mode)) { - if (pushd(n->name)) + if (S_ISDIR(n->inode->base.mode)) { + if (pushd((const char *)n->name)) return -1; - for (c = n->data.dir->children; c != NULL; c = c->next) { - if (set_attribs(fs, c, flags)) + for (c = n->children; c != NULL; c = c->next) { + if (set_attribs(xattr, c, flags)) return -1; } @@ -110,38 +184,21 @@ static int set_attribs(fstree_t *fs, tree_node_t *n, int flags) } #ifdef HAVE_SYS_XATTR_H - if ((flags & UNPACK_SET_XATTR) && n->xattr != NULL) { - size_t i, len, kidx, vidx; - const char *key, *value; - - for (i = 0; i < n->xattr->num_attr; ++i) { - kidx = n->xattr->attr[i].key_index; - vidx = n->xattr->attr[i].value_index; - - key = str_table_get_string(&fs->xattr_keys, kidx); - value = str_table_get_string(&fs->xattr_values, vidx); - len = strlen(value); - - if (lsetxattr(n->name, key, value, len, 0)) { - fprintf(stderr, - "setting xattr '%s' on %s: %s\n", - key, n->name, strerror(errno)); - return -1; - } - } + if ((flags & UNPACK_SET_XATTR) && xattr != NULL) { + if (set_xattr(xattr, n)) + return -1; } -#else - (void)fs; #endif if (flags & UNPACK_SET_TIMES) { struct timespec times[2]; memset(times, 0, sizeof(times)); - times[0].tv_sec = n->mod_time; - times[1].tv_sec = n->mod_time; + times[0].tv_sec = n->inode->base.mod_time; + times[1].tv_sec = n->inode->base.mod_time; - if (utimensat(AT_FDCWD, n->name, times, AT_SYMLINK_NOFOLLOW)) { + if (utimensat(AT_FDCWD, (const char *)n->name, times, + AT_SYMLINK_NOFOLLOW)) { fprintf(stderr, "setting timestamp on %s: %s\n", n->name, strerror(errno)); return -1; @@ -149,7 +206,7 @@ static int set_attribs(fstree_t *fs, tree_node_t *n, int flags) } if (flags & UNPACK_CHOWN) { - if (fchownat(AT_FDCWD, n->name, n->uid, n->gid, + if (fchownat(AT_FDCWD, (const char *)n->name, n->uid, n->gid, AT_SYMLINK_NOFOLLOW)) { fprintf(stderr, "chown %s: %s\n", n->name, strerror(errno)); @@ -157,8 +214,9 @@ static int set_attribs(fstree_t *fs, tree_node_t *n, int flags) } } - if (flags & UNPACK_CHMOD && !S_ISLNK(n->mode)) { - if (fchmodat(AT_FDCWD, n->name, n->mode, 0)) { + if (flags & UNPACK_CHMOD && !S_ISLNK(n->inode->base.mode)) { + if (fchmodat(AT_FDCWD, (const char *)n->name, + n->inode->base.mode & ~S_IFMT, 0)) { fprintf(stderr, "chmod %s: %s\n", n->name, strerror(errno)); return -1; @@ -167,16 +225,16 @@ static int set_attribs(fstree_t *fs, tree_node_t *n, int flags) return 0; } -int restore_fstree(tree_node_t *root, int flags) +int restore_fstree(sqfs_tree_node_t *root, int flags) { - tree_node_t *n, *old_parent; + sqfs_tree_node_t *n, *old_parent; /* make sure fstree_get_path() stops at this node */ old_parent = root->parent; root->parent = NULL; - if (S_ISDIR(root->mode)) { - for (n = root->data.dir->children; n != NULL; n = n->next) { + if (S_ISDIR(root->inode->base.mode)) { + for (n = root->children; n != NULL; n = n->next) { if (create_node(n, flags)) return -1; } @@ -189,20 +247,23 @@ int restore_fstree(tree_node_t *root, int flags) return 0; } -int update_tree_attribs(fstree_t *fs, tree_node_t *root, int flags) +int update_tree_attribs(sqfs_xattr_reader_t *xattr, + const sqfs_tree_node_t *root, int flags) { - tree_node_t *n; + const sqfs_tree_node_t *n; - if ((flags & (UNPACK_CHOWN | UNPACK_CHMOD | UNPACK_SET_TIMES)) == 0) + if ((flags & (UNPACK_CHOWN | UNPACK_CHMOD | + UNPACK_SET_TIMES | UNPACK_SET_XATTR)) == 0) { return 0; + } - if (S_ISDIR(root->mode)) { - for (n = root->data.dir->children; n != NULL; n = n->next) { - if (set_attribs(fs, n, flags)) + if (S_ISDIR(root->inode->base.mode)) { + for (n = root->children; n != NULL; n = n->next) { + if (set_attribs(xattr, n, flags)) return -1; } } else { - if (set_attribs(fs, root, flags)) + if (set_attribs(xattr, root, flags)) return -1; } |