diff options
Diffstat (limited to 'unpack/restore_fstree.c')
-rw-r--r-- | unpack/restore_fstree.c | 320 |
1 files changed, 0 insertions, 320 deletions
diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c deleted file mode 100644 index 8f99439..0000000 --- a/unpack/restore_fstree.c +++ /dev/null @@ -1,320 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * restore_fstree.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#include "rdsquashfs.h" - -#ifdef _WIN32 -static int create_node(const sqfs_tree_node_t *n, const char *name) -{ - WCHAR *wpath; - HANDLE fh; - - wpath = path_to_windows(name); - if (wpath == NULL) - return -1; - - switch (n->inode->base.mode & S_IFMT) { - case S_IFDIR: - if (!CreateDirectoryW(wpath, NULL)) - goto fail; - break; - case S_IFREG: - fh = CreateFileW(wpath, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, CREATE_NEW, 0, NULL); - - if (fh == INVALID_HANDLE_VALUE) - goto fail; - - CloseHandle(fh); - break; - default: - break; - } - - free(wpath); - return 0; -fail: - fprintf(stderr, "Creating %s: %ld\n", name, GetLastError()); - free(wpath); - return -1; -} -#else -static int create_node(const sqfs_tree_node_t *n, const char *name) -{ - sqfs_u32 devno; - int fd; - - switch (n->inode->base.mode & S_IFMT) { - case S_IFDIR: - if (mkdir(name, 0755) && errno != EEXIST) { - fprintf(stderr, "mkdir %s: %s\n", - name, strerror(errno)); - return -1; - } - break; - case S_IFLNK: - if (symlink((const char *)n->inode->extra, name)) { - fprintf(stderr, "ln -s %s %s: %s\n", - (const char *)n->inode->extra, name, - strerror(errno)); - return -1; - } - break; - case S_IFSOCK: - case S_IFIFO: - if (mknod(name, (n->inode->base.mode & S_IFMT) | 0700, 0)) { - fprintf(stderr, "creating %s: %s\n", - name, strerror(errno)); - return -1; - } - break; - case S_IFBLK: - case S_IFCHR: - 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(name, n->inode->base.mode & S_IFMT, devno)) { - fprintf(stderr, "creating device %s: %s\n", - name, strerror(errno)); - return -1; - } - break; - case S_IFREG: - fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0600); - - if (fd < 0) { - fprintf(stderr, "creating %s: %s\n", - name, strerror(errno)); - return -1; - } - - close(fd); - break; - default: - break; - } - - return 0; -} -#endif - -static int create_node_dfs(const sqfs_tree_node_t *n, int flags) -{ - const sqfs_tree_node_t *c; - char *name; - int ret; - - if (!is_filename_sane((const char *)n->name, true)) { - fprintf(stderr, "Found an entry named '%s', skipping.\n", - n->name); - return 0; - } - - name = sqfs_tree_node_get_path(n); - if (name == NULL) { - fprintf(stderr, "Constructing full path for '%s': %s\n", - (const char *)n->name, strerror(errno)); - return -1; - } - - ret = canonicalize_name(name); - assert(ret == 0); - - if (!(flags & UNPACK_QUIET)) - printf("creating %s\n", name); - - ret = create_node(n, name); - free(name); - if (ret) - return -1; - - if (S_ISDIR(n->inode->base.mode)) { - for (c = n->children; c != NULL; c = c->next) { - if (create_node_dfs(c, flags)) - return -1; - } - } - return 0; -} - -#ifdef HAVE_SYS_XATTR_H -static int set_xattr(const char *path, 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; - sqfs_u32 index; - size_t i; - int ret; - - sqfs_inode_get_xattr_index(n->inode, &index); - - 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 (sqfs_xattr_reader_read_value(xattr, key, &value)) { - fputs("Error reading xattr value\n", stderr); - free(key); - return -1; - } - - ret = lsetxattr(path, (const char *)key->key, - value->value, value->size, 0); - if (ret) { - fprintf(stderr, "setting xattr '%s' on %s: %s\n", - key->key, path, strerror(errno)); - } - - free(key); - free(value); - if (ret) - return -1; - } - - return 0; -} -#endif - -static int set_attribs(sqfs_xattr_reader_t *xattr, - const sqfs_tree_node_t *n, int flags) -{ - const sqfs_tree_node_t *c; - char *path; - int ret; - - if (!is_filename_sane((const char *)n->name, true)) - return 0; - - if (S_ISDIR(n->inode->base.mode)) { - for (c = n->children; c != NULL; c = c->next) { - if (set_attribs(xattr, c, flags)) - return -1; - } - } - - path = sqfs_tree_node_get_path(n); - if (path == NULL) { - fprintf(stderr, "Reconstructing full path: %s\n", - strerror(errno)); - return -1; - } - - ret = canonicalize_name(path); - assert(ret == 0); - -#ifdef HAVE_SYS_XATTR_H - if ((flags & UNPACK_SET_XATTR) && xattr != NULL) { - if (set_xattr(path, xattr, n)) - goto fail; - } -#endif - -#ifndef _WIN32 - if (flags & UNPACK_SET_TIMES) { - struct timespec times[2]; - - memset(times, 0, sizeof(times)); - times[0].tv_sec = n->inode->base.mod_time; - times[1].tv_sec = n->inode->base.mod_time; - - if (utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW)) { - fprintf(stderr, "setting timestamp on %s: %s\n", - path, strerror(errno)); - goto fail; - } - } -#endif - if (flags & UNPACK_CHOWN) { - if (fchownat(AT_FDCWD, path, n->uid, n->gid, - AT_SYMLINK_NOFOLLOW)) { - fprintf(stderr, "chown %s: %s\n", - path, strerror(errno)); - goto fail; - } - } - - if (flags & UNPACK_CHMOD && !S_ISLNK(n->inode->base.mode)) { - if (fchmodat(AT_FDCWD, path, - n->inode->base.mode & ~S_IFMT, 0)) { - fprintf(stderr, "chmod %s: %s\n", - path, strerror(errno)); - goto fail; - } - } - - free(path); - return 0; -fail: - free(path); - return -1; -} - -int restore_fstree(sqfs_tree_node_t *root, int flags) -{ - 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->inode->base.mode)) { - for (n = root->children; n != NULL; n = n->next) { - if (create_node_dfs(n, flags)) - return -1; - } - } else { - if (create_node_dfs(root, flags)) - return -1; - } - - root->parent = old_parent; - return 0; -} - -int update_tree_attribs(sqfs_xattr_reader_t *xattr, - const sqfs_tree_node_t *root, int flags) -{ - const sqfs_tree_node_t *n; - - if ((flags & (UNPACK_CHOWN | UNPACK_CHMOD | - UNPACK_SET_TIMES | UNPACK_SET_XATTR)) == 0) { - return 0; - } - - 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(xattr, root, flags)) - return -1; - } - - return 0; -} |