- 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;
+ }
+ progress->extract.num_streams = num_streams;
+ progress->extract.total_bytes = total_bytes;
+ progress->extract.completed_bytes = 0;
+}
+
+static void
+maybe_add_stream_for_extraction(struct wim_lookup_table_entry *lte,
+ struct list_head *stream_list)
+{
+ if (++lte->out_refcnt == 1) {
+ INIT_LIST_HEAD(<e->lte_dentry_list);
+ list_add_tail(<e->extraction_list, stream_list);
+ }
+}
+
+struct find_streams_ctx {
+ struct list_head stream_list;
+ int extract_flags;
+};
+
+static int
+dentry_find_streams_to_extract(struct wim_dentry *dentry, void *_ctx)
+{
+ struct find_streams_ctx *ctx = _ctx;
+ struct wim_inode *inode = dentry->d_inode;
+ struct wim_lookup_table_entry *lte;
+ bool dentry_added = false;
+ struct list_head *stream_list = &ctx->stream_list;
+ int extract_flags = ctx->extract_flags;
+
+ if (!dentry->needs_extraction)
+ return 0;
+
+ lte = inode_unnamed_lte_resolved(inode);
+ if (lte) {
+ if (!inode->i_visited)
+ maybe_add_stream_for_extraction(lte, stream_list);
+ list_add_tail(&dentry->extraction_stream_list, <e->lte_dentry_list);
+ dentry_added = true;
+ }
+
+ /* Determine whether to include alternate data stream entries or not.
+ *
+ * UNIX: Include them if extracting using NTFS-3g.
+ *
+ * Windows: Include them undconditionally, although if the filesystem is
+ * not NTFS we won't actually be able to extract them. */
+#if defined(WITH_NTFS_3G)
+ if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS)
+#elif defined(__WIN32__)
+ if (1)
+#else
+ if (0)
+#endif
+ {
+ for (unsigned i = 0; i < inode->i_num_ads; i++) {
+ if (inode->i_ads_entries[i].stream_name_nbytes != 0) {
+ lte = inode->i_ads_entries[i].lte;
+ if (lte) {
+ if (!inode->i_visited) {
+ maybe_add_stream_for_extraction(lte,
+ stream_list);
+ }
+ if (!dentry_added) {
+ list_add_tail(&dentry->extraction_stream_list,
+ <e->lte_dentry_list);
+ dentry_added = true;
+ }
+ }
+ }