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;
}
#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) {