if (lchown(link, unix_data->uid, unix_data->gid)) {
if (errno == EPERM) {
/* Ignore */
- WARNING_WITH_ERRNO("failed to set symlink UNIX owner/group");
+ WARNING_WITH_ERRNO("failed to set symlink UNIX "
+ "owner/group on \"%s\"", link);
} else {
- ERROR_WITH_ERRNO("failed to set symlink UNIX owner/group");
+ ERROR_WITH_ERRNO("failed to set symlink UNIX "
+ "owner/group on \"%s\"", link);
return WIMLIB_ERR_INVALID_DENTRY;
}
}
}
static int
-fd_apply_unix_data(int fd, const struct wimlib_unix_data *unix_data)
+fd_apply_unix_data(int fd, const char *path,
+ const struct wimlib_unix_data *unix_data)
{
if (fchown(fd, unix_data->uid, unix_data->gid)) {
if (errno == EPERM) {
- WARNING_WITH_ERRNO("failed to set file UNIX owner/group");
+ WARNING_WITH_ERRNO("failed to set file UNIX "
+ "owner/group on \"%s\"", path);
/* Ignore? */
} else {
- ERROR_WITH_ERRNO("failed to set file UNIX owner/group");
+ ERROR_WITH_ERRNO("failed to set file UNIX "
+ "owner/group on \"%s\"", path);
return WIMLIB_ERR_INVALID_DENTRY;
}
}
if (fchmod(fd, unix_data->mode)) {
if (errno == EPERM) {
- WARNING_WITH_ERRNO("failed to set UNIX file mode");
+ WARNING_WITH_ERRNO("failed to set UNIX file mode "
+ "on \"%s\"", path);
/* Ignore? */
} else {
- ERROR_WITH_ERRNO("failed to set UNIX file mode");
+ ERROR_WITH_ERRNO("failed to set UNIX file mode "
+ "on \"%s\"", path);
return WIMLIB_ERR_INVALID_DENTRY;
}
}
int dfd = open(dir, O_RDONLY);
int ret;
if (dfd >= 0) {
- ret = fd_apply_unix_data(dfd, unix_data);
+ ret = fd_apply_unix_data(dfd, dir, unix_data);
if (close(dfd)) {
ERROR_WITH_ERRNO("can't close directory `%s'", dir);
ret = WIMLIB_ERR_MKDIR;
else if (ret < 0)
ret = 0;
else
- ret = fd_apply_unix_data(out_fd, &unix_data);
+ ret = fd_apply_unix_data(out_fd, output_path, &unix_data);
if (ret)
goto out;
}
{
char target[4096 + args->target_realpath_len];
char *fixed_target;
+ const struct wim_inode *inode = dentry->d_inode;
- ssize_t ret = inode_readlink(dentry->d_inode,
- target + args->target_realpath_len,
- sizeof(target) - args->target_realpath_len - 1,
- args->w, false);
+ ssize_t ret = wim_inode_readlink(inode,
+ target + args->target_realpath_len,
+ sizeof(target) - args->target_realpath_len - 1);
struct wim_lookup_table_entry *lte;
if (ret <= 0) {
output_path, fixed_target);
return WIMLIB_ERR_LINK;
}
- lte = inode_unnamed_lte_resolved(dentry->d_inode);
- wimlib_assert(lte != NULL);
if (args->extract_flags & WIMLIB_EXTRACT_FLAG_UNIX_DATA) {
struct wimlib_unix_data unix_data;
- ret = inode_get_unix_data(dentry->d_inode, &unix_data, NULL);
+ ret = inode_get_unix_data(inode, &unix_data, NULL);
if (ret > 0)
;
else if (ret < 0)
if (ret)
return ret;
}
+ lte = inode_unnamed_lte_resolved(inode);
+ wimlib_assert(lte != NULL);
args->progress.extract.completed_bytes += wim_resource_size(lte);
return 0;
}
#endif
}
-/* Extract a dentry if it hasn't already been extracted, and either the dentry
- * has no streams or WIMLIB_EXTRACT_FLAG_NO_STREAMS is not specified. */
+/* Extract a dentry if it hasn't already been extracted and either
+ * WIMLIB_EXTRACT_FLAG_NO_STREAMS is not specified, or the dentry is a directory
+ * and/or has no unnamed stream. */
static int
maybe_apply_dentry(struct wim_dentry *dentry, void *arg)
{
if (dentry->is_extracted)
return 0;
- if (args->extract_flags & WIMLIB_EXTRACT_FLAG_NO_STREAMS)
- if (inode_unnamed_lte_resolved(dentry->d_inode))
- return 0;
+ if (args->extract_flags & WIMLIB_EXTRACT_FLAG_NO_STREAMS &&
+ !dentry_is_directory(dentry) &&
+ inode_unnamed_lte_resolved(dentry->d_inode) != NULL)
+ return 0;
if ((args->extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE) &&
args->progress_func) {