+/*
+ * Extracts a regular file from the WIM archive.
+ */
+static int extract_regular_file(WIMStruct *w,
+ struct dentry *dentry,
+ const char *output_dir,
+ const char *output_path,
+ int extract_flags)
+{
+ struct lookup_table_entry *lte;
+ const struct inode *inode = dentry->d_inode;
+
+ lte = inode_unnamed_lte(inode, w->lookup_table);
+
+ if ((extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK |
+ WIMLIB_EXTRACT_FLAG_HARDLINK)) && lte) {
+ if (lte->extracted_file) {
+ return extract_regular_file_linked(dentry, output_dir,
+ output_path,
+ extract_flags, lte);
+ } else {
+ lte->extracted_file = STRDUP(output_path);
+ if (!lte->extracted_file)
+ return WIMLIB_ERR_NOMEM;
+ }
+ }
+
+ return extract_regular_file_unlinked(w, dentry, output_path,
+ extract_flags, lte);
+
+}
+
+static int extract_symlink(const struct dentry *dentry, const char *output_path,
+ const WIMStruct *w)
+{
+ char target[4096];
+ ssize_t ret = inode_readlink(dentry->d_inode, 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;
+}
+