+ for (i = 0; i < num_path_components; i++) {
+ *p++ = '.';
+ *p++ = '.';
+ *p++ = '/';
+ }
+ p2 = lte->extracted_file;
+ while (*p2 == '/')
+ p2++;
+ while (num_output_dir_path_components--)
+ p2 = path_next_part(p2, NULL);
+ strcpy(p, p2);
+ if (symlink(buf, output_path) != 0) {
+ ERROR_WITH_ERRNO("Failed to symlink `%s' to "
+ "`%s'",
+ buf, lte->extracted_file);
+ return WIMLIB_ERR_LINK;
+ }
+
+ }
+ return 0;
+}
+
+static int extract_regular_file_unlinked(WIMStruct *w,
+ struct dentry *dentry,
+ const char *output_path,
+ int extract_flags,
+ struct lookup_table_entry *lte)
+{
+ /* Normal mode of extraction. Regular files and hard links are
+ * extracted in the way that they appear in the WIM. */
+
+ int out_fd;
+ int ret;
+ struct inode *inode = dentry->d_inode;
+
+ if (!((extract_flags & WIMLIB_EXTRACT_FLAG_MULTI_IMAGE)
+ && (extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK |
+ WIMLIB_EXTRACT_FLAG_HARDLINK))))
+ {
+ /* If the dentry is one of a hard link set of at least 2
+ * dentries and one of the other dentries has already been
+ * extracted, make a hard link to the file corresponding to this
+ * already-extracted directory. Otherwise, extract the file,
+ * and set the inode->extracted_file field so that other
+ * dentries in the hard link group can link to it. */
+ if (inode->link_count > 1) {
+ if (inode->extracted_file) {
+ DEBUG("Extracting hard link `%s' => `%s'",
+ output_path, inode->extracted_file);
+ if (link(inode->extracted_file, output_path) != 0) {
+ ERROR_WITH_ERRNO("Failed to hard link "
+ "`%s' to `%s'",
+ output_path,
+ inode->extracted_file);
+ return WIMLIB_ERR_LINK;
+ }
+ return 0;