diff options
Diffstat (limited to 'unpack')
| -rw-r--r-- | unpack/rdsquashfs.c | 11 | ||||
| -rw-r--r-- | unpack/restore_fstree.c | 116 | 
2 files changed, 69 insertions, 58 deletions
| diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c index 2f84264..4acc71e 100644 --- a/unpack/rdsquashfs.c +++ b/unpack/rdsquashfs.c @@ -135,10 +135,12 @@ int main(int argc, char **argv)  	case OP_UNPACK:  		if (opt.unpack_root != NULL) {  			if (mkdir_p(opt.unpack_root)) -				return -1; +				goto out; -			if (pushd(opt.unpack_root)) -				return -1; +			if (chdir(opt.unpack_root)) { +				perror(opt.unpack_root); +				goto out; +			}  		}  		if (restore_fstree(n, opt.flags)) @@ -149,9 +151,6 @@ int main(int argc, char **argv)  		if (update_tree_attribs(xattr, n, opt.flags))  			goto out; - -		if (opt.unpack_root != NULL && popd() != 0) -			goto out;  		break;  	case OP_DESCRIBE:  		if (describe_tree(n, opt.unpack_root)) diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c index 6995d47..dac1a8c 100644 --- a/unpack/restore_fstree.c +++ b/unpack/restore_fstree.c @@ -18,50 +18,49 @@ static int create_node(const sqfs_tree_node_t *n, int flags)  		return 0;  	} -	if (!(flags & UNPACK_QUIET)) { -		name = sqfs_tree_node_get_path(n); -		if (name != NULL) { -			ret = canonicalize_name(name); -			assert(ret == 0); -			printf("creating %s\n", name); -			free(name); -		} +	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); +  	switch (n->inode->base.mode & S_IFMT) {  	case S_IFDIR: -		if (mkdir((const char *)n->name, 0755) && errno != EEXIST) { +		if (mkdir(name, 0755) && errno != EEXIST) {  			fprintf(stderr, "mkdir %s: %s\n", -				n->name, strerror(errno)); -			return -1; +				name, strerror(errno)); +			goto fail;  		} -		if (pushd((const char *)n->name)) -			return -1; +		free(name); +		name = NULL;  		for (c = n->children; c != NULL; c = c->next) {  			if (create_node(c, flags)) -				return -1; +				goto fail;  		} - -		if (popd()) -			return -1;  		break;  	case S_IFLNK: -		if (symlink(n->inode->slink_target, (const char *)n->name)) { +		if (symlink(n->inode->slink_target, name)) {  			fprintf(stderr, "ln -s %s %s: %s\n", -				n->inode->slink_target, n->name, +				n->inode->slink_target, name,  				strerror(errno)); -			return -1; +			goto fail;  		}  		break;  	case S_IFSOCK:  	case S_IFIFO: -		if (mknod((const char *)n->name, -			  (n->inode->base.mode & S_IFMT) | 0700, 0)) { +		if (mknod(name, (n->inode->base.mode & S_IFMT) | 0700, 0)) {  			fprintf(stderr, "creating %s: %s\n", -				n->name, strerror(errno)); -			return -1; +				name, strerror(errno)); +			goto fail;  		}  		break;  	case S_IFBLK: @@ -75,21 +74,19 @@ static int create_node(const sqfs_tree_node_t *n, int flags)  			devno = n->inode->data.dev.devno;  		} -		if (mknod((const char *)n->name, n->inode->base.mode & S_IFMT, -			  devno)) { +		if (mknod(name, n->inode->base.mode & S_IFMT, devno)) {  			fprintf(stderr, "creating device %s: %s\n", -				n->name, strerror(errno)); -			return -1; +				name, strerror(errno)); +			goto fail;  		}  		break;  	}  	case S_IFREG: -		fd = open((const char *)n->name, O_WRONLY | O_CREAT | O_EXCL, -			  0600); +		fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0600);  		if (fd < 0) {  			fprintf(stderr, "creating %s: %s\n", -				n->name, strerror(errno)); -			return -1; +				name, strerror(errno)); +			goto fail;  		}  		close(fd); @@ -98,11 +95,16 @@ static int create_node(const sqfs_tree_node_t *n, int flags)  		break;  	} +	free(name);  	return 0; +fail: +	free(name); +	return -1;  }  #ifdef HAVE_SYS_XATTR_H -static int set_xattr(sqfs_xattr_reader_t *xattr, const sqfs_tree_node_t *n) +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; @@ -138,11 +140,11 @@ static int set_xattr(sqfs_xattr_reader_t *xattr, const sqfs_tree_node_t *n)  			return -1;  		} -		ret = lsetxattr((const char *)n->name, (const char *)key->key, +		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, n->name, strerror(errno)); +				key->key, path, strerror(errno));  		}  		free(key); @@ -159,27 +161,33 @@ 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))  		return 0;  	if (S_ISDIR(n->inode->base.mode)) { -		if (pushd((const char *)n->name)) -			return -1; -  		for (c = n->children; c != NULL; c = c->next) {  			if (set_attribs(xattr, c, flags))  				return -1;  		} +	} -		if (popd()) -			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(xattr, n)) -			return -1; +		if (set_xattr(path, xattr, n)) +			goto fail;  	}  #endif @@ -190,32 +198,36 @@ static int set_attribs(sqfs_xattr_reader_t *xattr,  		times[0].tv_sec = n->inode->base.mod_time;  		times[1].tv_sec = n->inode->base.mod_time; -		if (utimensat(AT_FDCWD, (const char *)n->name, times, -			      AT_SYMLINK_NOFOLLOW)) { +		if (utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW)) {  			fprintf(stderr, "setting timestamp on %s: %s\n", -				n->name, strerror(errno)); -			return -1; +				path, strerror(errno)); +			goto fail;  		}  	}  	if (flags & UNPACK_CHOWN) { -		if (fchownat(AT_FDCWD, (const char *)n->name, n->uid, n->gid, +		if (fchownat(AT_FDCWD, path, n->uid, n->gid,  			     AT_SYMLINK_NOFOLLOW)) {  			fprintf(stderr, "chown %s: %s\n", -				n->name, strerror(errno)); -			return -1; +				path, strerror(errno)); +			goto fail;  		}  	}  	if (flags & UNPACK_CHMOD && !S_ISLNK(n->inode->base.mode)) { -		if (fchmodat(AT_FDCWD, (const char *)n->name, +		if (fchmodat(AT_FDCWD, path,  			     n->inode->base.mode & ~S_IFMT, 0)) {  			fprintf(stderr, "chmod %s: %s\n", -				n->name, strerror(errno)); -			return -1; +				path, strerror(errno)); +			goto fail;  		}  	} + +	free(path);  	return 0; +fail: +	free(path); +	return -1;  }  int restore_fstree(sqfs_tree_node_t *root, int flags) | 
