X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fextract.c;h=1dd2f618479f0a879e3b4a4e560be1fd05c424a8;hb=6ae89e3fae1efba4a3d53b2793921f415b20e9fb;hp=26164028ee9d6dc5f73d2af2f1987f445abbd29d;hpb=67f45cecd793345416d5d85fbe37ec54b1bb6ef8;p=wimlib diff --git a/src/extract.c b/src/extract.c index 26164028..1dd2f618 100644 --- a/src/extract.c +++ b/src/extract.c @@ -126,27 +126,29 @@ static int extract_regular_file_unlinked(WIMStruct *w, int ret; struct inode *inode = dentry->inode; - if (!(extract_flags & WIMLIB_EXTRACT_FLAG_MULTI_IMAGE)) { - /* This dentry is one of a hard link set of at least 2 dentries. - * If 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 dentry->extracted_file field so that other + 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. */ - struct dentry *other; - 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; - } 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; + } FREE(inode->extracted_file); inode->extracted_file = STRDUP(output_path); if (!inode->extracted_file) { @@ -169,16 +171,16 @@ static int extract_regular_file_unlinked(WIMStruct *w, /* Empty file with no lookup table entry */ DEBUG("Empty file `%s'.", output_path); ret = 0; - goto done; + goto out; } ret = extract_full_wim_resource_to_fd(lte, out_fd); if (ret != 0) { ERROR("Failed to extract resource to `%s'", output_path); - goto done; + goto out; } -done: +out: if (close(out_fd) != 0) { ERROR_WITH_ERRNO("Failed to close file `%s'", output_path); ret = WIMLIB_ERR_WRITE; @@ -202,13 +204,15 @@ static int extract_regular_file(WIMStruct *w, if ((extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) && lte) { - if (++lte->out_refcnt != 1) + if (lte->extracted_file) { return extract_regular_file_linked(dentry, output_dir, output_path, extract_flags, lte); - lte->extracted_file = STRDUP(output_path); - if (!lte->extracted_file) - return WIMLIB_ERR_NOMEM; + } else { + lte->extracted_file = STRDUP(output_path); + if (!lte->extracted_file) + return WIMLIB_ERR_NOMEM; + } } return extract_regular_file_unlinked(w, dentry, output_path, @@ -426,8 +430,7 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w, int image, w->lookup_table = joined_tab; } - - for_lookup_table_entry(w->lookup_table, zero_out_refcnts, NULL); + for_lookup_table_entry(w->lookup_table, lte_free_extracted_file, NULL); if (image == WIM_ALL_IMAGES) { flags |= WIMLIB_EXTRACT_FLAG_MULTI_IMAGE;