diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-05-03 23:33:41 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-05-03 23:33:41 +0200 |
commit | 6f7ee71165b30272a4f18bca361c324c7671680c (patch) | |
tree | 7f830e22992358f8a55082fad9e5890458af054a /unpack/restore_fstree.c | |
parent | 9de5c93986bc6a4b33f3f50ed2a94c9aa3a33c7f (diff) |
unsquashfs: add flags to filter what file types to unpack
This allows the user to skip stuff like device special files (which
non-root can't create anyway) or to not create symlinks/fifos etc...
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'unpack/restore_fstree.c')
-rw-r--r-- | unpack/restore_fstree.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c index 56c3cc5..8ef21c3 100644 --- a/unpack/restore_fstree.c +++ b/unpack/restore_fstree.c @@ -3,14 +3,14 @@ static int restore_directory(int dirfd, tree_node_t *n, compressor_t *cmp, size_t block_size, frag_reader_t *frag, - int sqfsfd) + int sqfsfd, int flags) { int fd; for (n = n->data.dir->children; n != NULL; n = n->next) { switch (n->mode & S_IFMT) { case S_IFDIR: - if (mkdirat(dirfd, n->name, n->mode) && + if (mkdirat(dirfd, n->name, 0755) && errno != EEXIST) { fprintf(stderr, "mkdir %s: %s\n", n->name, strerror(errno)); @@ -25,7 +25,7 @@ static int restore_directory(int dirfd, tree_node_t *n, compressor_t *cmp, } if (restore_directory(fd, n, cmp, block_size, - frag, sqfsfd)) { + frag, sqfsfd, flags)) { close(fd); return -1; } @@ -42,7 +42,8 @@ static int restore_directory(int dirfd, tree_node_t *n, compressor_t *cmp, break; case S_IFSOCK: case S_IFIFO: - if (mknodat(dirfd, n->name, n->mode, 0)) { + if (mknodat(dirfd, n->name, + (n->mode & S_IFMT) | 0700, 0)) { fprintf(stderr, "creating %s: %s\n", n->name, strerror(errno)); return -1; @@ -50,7 +51,8 @@ static int restore_directory(int dirfd, tree_node_t *n, compressor_t *cmp, break; case S_IFBLK: case S_IFCHR: - if (mknodat(dirfd, n->name, n->mode, n->data.devno)) { + if (mknodat(dirfd, n->name, (n->mode & S_IFMT), + n->data.devno)) { fprintf(stderr, "creating device %s: %s\n", n->name, strerror(errno)); return -1; @@ -58,7 +60,7 @@ static int restore_directory(int dirfd, tree_node_t *n, compressor_t *cmp, break; case S_IFREG: fd = openat(dirfd, n->name, - O_WRONLY | O_CREAT | O_EXCL, n->mode); + O_WRONLY | O_CREAT | O_EXCL, 0600); if (fd < 0) { fprintf(stderr, "creating %s: %s\n", n->name, strerror(errno)); @@ -76,13 +78,32 @@ static int restore_directory(int dirfd, tree_node_t *n, compressor_t *cmp, default: break; } + + if (flags & UNPACK_CHOWN) { + if (fchownat(dirfd, n->name, n->uid, n->gid, + AT_SYMLINK_NOFOLLOW)) { + fprintf(stderr, "chown %s: %s\n", + n->name, strerror(errno)); + return -1; + } + } + + if (flags & UNPACK_CHMOD) { + if (fchmodat(dirfd, n->name, n->mode, + AT_SYMLINK_NOFOLLOW)) { + fprintf(stderr, "chmod %s: %s\n", + n->name, strerror(errno)); + return -1; + } + } } return 0; } int restore_fstree(const char *rootdir, tree_node_t *root, compressor_t *cmp, - size_t block_size, frag_reader_t *frag, int sqfsfd) + size_t block_size, frag_reader_t *frag, int sqfsfd, + int flags) { int dirfd; @@ -95,7 +116,8 @@ int restore_fstree(const char *rootdir, tree_node_t *root, compressor_t *cmp, return -1; } - if (restore_directory(dirfd, root, cmp, block_size, frag, sqfsfd)) { + if (restore_directory(dirfd, root, cmp, block_size, frag, + sqfsfd, flags)) { close(dirfd); return -1; } |