#ifdef WITH_NTFS_3G
#include <ntfs-3g/volume.h>
+#include <ntfs-3g/security.h>
#endif
/* Sets and creates the directory to which files are to be extracted when
*/
static int extract_regular_file(WIMStruct *w,
const struct dentry *dentry,
- const char *output_path)
+ const char *output_path,
+ int extract_flags)
{
struct lookup_table_entry *lte;
int ret;
int out_fd;
const struct resource_entry *res_entry;
- lte = lookup_resource(w->lookup_table, dentry->hash);
+ lte = __lookup_resource(w->lookup_table, dentry_hash(dentry));
/* If we already extracted the same file or a hard link copy of it, we
* may be able to simply create a link. The exact action is specified
* by the current @link_type. */
- if ((w->extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) &&
+ if ((extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) &&
lte && lte->out_refcnt != 0)
{
wimlib_assert(lte->file_on_disk);
- if (w->extract_flags & WIMLIB_EXTRACT_FLAG_HARDLINK) {
+ if (extract_flags & WIMLIB_EXTRACT_FLAG_HARDLINK) {
if (link(lte->file_on_disk, output_path) != 0) {
ERROR_WITH_ERRNO("Failed to hard link "
"`%s' to `%s'",
return ret;
}
+static int extract_symlink(const struct dentry *dentry, const char *output_path,
+ const WIMStruct *w)
+{
+ char target[4096];
+ ssize_t ret = dentry_readlink(dentry, target, sizeof(target), w);
+ if (ret <= 0) {
+ ERROR("Could not read the symbolic link from dentry `%s'",
+ dentry->full_path_utf8);
+ return WIMLIB_ERR_INVALID_DENTRY;
+ }
+ ret = symlink(target, output_path);
+ if (ret != 0) {
+ ERROR_WITH_ERRNO("Failed to symlink `%s' to `%s'",
+ output_path, target);
+ return WIMLIB_ERR_LINK;
+ }
+ return 0;
+}
+
/*
* Extracts a directory from the WIM archive.
*
return 0;
}
+struct extract_args {
+ WIMStruct *w;
+ int extract_flags;
+#ifdef WITH_NTFS_3G
+ struct SECURITY_API *scapi;
+#endif
+};
/*
* Extracts a file or directory from the WIM archive. For use in
* @dentry: The dentry to extract.
* @arg: A pointer to the WIMStruct for the WIM file.
*/
-static int extract_regular_file_or_directory(struct dentry *dentry, void *arg)
+static int extract_dentry(struct dentry *dentry, void *arg)
{
- WIMStruct *w = (WIMStruct*)arg;
+ struct extract_args *args = arg;
+ WIMStruct *w = args->w;
+ int extract_flags = args->extract_flags;
size_t len = strlen(w->output_dir);
char output_path[len + dentry->full_path_utf8_len + 1];
+ int ret = 0;
- if (w->extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE)
+ if (extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE)
puts(dentry->full_path_utf8);
memcpy(output_path, w->output_dir, len);
memcpy(output_path + len, dentry->full_path_utf8, dentry->full_path_utf8_len);
output_path[len + dentry->full_path_utf8_len] = '\0';
- if (dentry_is_regular_file(dentry)) {
- return extract_regular_file(w, dentry, output_path);
+ if (dentry_is_symlink(dentry)) {
+ ret = extract_symlink(dentry, output_path, w);
+ } else if (dentry_is_directory(dentry)) {
+ if (!dentry_is_root(dentry)) /* Root doesn't need to be extracted. */
+ ret = extract_directory(dentry, output_path);
} else {
- if (dentry_is_root(dentry)) /* Root doesn't need to be extracted. */
- return 0;
- else
- return extract_directory(dentry, output_path);
+ ret = extract_regular_file(w, dentry, output_path, extract_flags);
}
}
-static int extract_single_image(WIMStruct *w, int image)
+
+static int extract_single_image(WIMStruct *w, int image, int extract_flags)
{
DEBUG("Extracting image %d", image);
if (ret != 0)
return ret;
- return for_dentry_in_tree(wim_root_dentry(w),
- extract_regular_file_or_directory, w);
+ struct extract_args args = {
+ .w = w,
+ .extract_flags = extract_flags,
+ #ifdef WITH_NTFS_3G
+ .scapi = NULL
+ #endif
+ };
+
+ return for_dentry_in_tree(wim_root_dentry(w), extract_dentry, &args);
}
/* Extracts all images from the WIM to w->output_dir, with the images placed in
* subdirectories named by their image names. */
-static int extract_all_images(WIMStruct *w)
+static int extract_all_images(WIMStruct *w, int extract_flags)
{
size_t image_name_max_len = max(xml_get_max_image_name_len(w), 20);
size_t output_path_len = strlen(w->output_dir);
ret = set_output_dir(w, buf);
if (ret != 0)
goto done;
- ret = extract_single_image(w, image);
+ ret = extract_single_image(w, image, extract_flags);
if (ret != 0)
goto done;
}
return WIMLIB_ERR_UNSUPPORTED;
#endif
}
- w->extract_flags = flags;
if (image == WIM_ALL_IMAGES) {
w->is_multi_image_extraction = true;
- ret = extract_all_images(w);
+ ret = extract_all_images(w, flags);
} else {
w->is_multi_image_extraction = false;
- ret = extract_single_image(w, image);
+ ret = extract_single_image(w, image, flags);
}
return ret;