]> wimlib.net Git - wimlib/blobdiff - src/extract.c
Support file counts for extract file structure and metadata progress
[wimlib] / src / extract.c
index e8fd7a69ce5211f8d95ca7efd5d14765258c6e96..8e35994aa6a48c60079c31198c1c7a25fdeffa24 100644 (file)
 int
 do_file_extract_progress(struct apply_ctx *ctx, enum wimlib_progress_msg msg)
 {
-       ctx->count_until_file_progress = 512;  /* Arbitrary value to limit calls  */
+       ctx->count_until_file_progress = 500;  /* Arbitrary value to limit calls  */
        return extract_progress(ctx, msg);
 }
 
+static int
+start_file_phase(struct apply_ctx *ctx, uint64_t end_file_count, enum wimlib_progress_msg msg)
+{
+       ctx->progress.extract.current_file_count = 0;
+       ctx->progress.extract.end_file_count = end_file_count;
+       return do_file_extract_progress(ctx, msg);
+}
+
+int
+start_file_structure_phase(struct apply_ctx *ctx, uint64_t end_file_count)
+{
+       return start_file_phase(ctx, end_file_count, WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE);
+}
+
+int
+start_file_metadata_phase(struct apply_ctx *ctx, uint64_t end_file_count)
+{
+       return start_file_phase(ctx, end_file_count, WIMLIB_PROGRESS_MSG_EXTRACT_METADATA);
+}
+
+static int
+end_file_phase(struct apply_ctx *ctx, enum wimlib_progress_msg msg)
+{
+       ctx->progress.extract.current_file_count = ctx->progress.extract.end_file_count;
+       return do_file_extract_progress(ctx, msg);
+}
+
+int
+end_file_structure_phase(struct apply_ctx *ctx)
+{
+       return end_file_phase(ctx, WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE);
+}
+
+int
+end_file_metadata_phase(struct apply_ctx *ctx)
+{
+       return end_file_phase(ctx, WIMLIB_PROGRESS_MSG_EXTRACT_METADATA);
+}
+
 /* Check whether the extraction of a dentry should be skipped completely.  */
 static bool
 dentry_is_supported(struct wim_dentry *dentry,
@@ -269,7 +308,7 @@ load_streams_from_pipe(struct apply_ctx *ctx,
        }
        ret = 0;
 out:
-       if (found_lte->resource_location != RESOURCE_IN_WIM)
+       if (found_lte && found_lte->resource_location != RESOURCE_IN_WIM)
                FREE(rspec);
        free_lookup_table_entry(found_lte);
        return ret;
@@ -412,6 +451,7 @@ extract_from_tmpfile(const tchar *tmpfile_name, struct apply_ctx *ctx)
        struct wim_lookup_table_entry *orig_lte = ctx->cur_stream;
        const struct read_stream_list_callbacks *cbs = ctx->saved_cbs;
        int ret;
+       const u32 orig_refcnt = orig_lte->out_refcnt;
 
        BUILD_BUG_ON(MAX_OPEN_STREAMS < ARRAY_LEN(orig_lte->inline_stream_owners));
 
@@ -428,7 +468,7 @@ extract_from_tmpfile(const tchar *tmpfile_name, struct apply_ctx *ctx)
        tmpfile_lte.resource_location = RESOURCE_IN_FILE_ON_DISK;
        tmpfile_lte.file_on_disk = ctx->tmpfile_name;
        ret = 0;
-       for (u32 i = 0; i < orig_lte->out_refcnt; i++) {
+       for (u32 i = 0; i < orig_refcnt; i++) {
 
                /* Note: it usually doesn't matter whether we pass the original
                 * stream entry to callbacks provided by the extraction backend
@@ -1480,23 +1520,20 @@ out:
 static int
 mkdir_if_needed(const tchar *target)
 {
-       struct stat stbuf;
-       if (tstat(target, &stbuf)) {
-               if (errno == ENOENT) {
-                       if (tmkdir(target, 0755)) {
-                               ERROR_WITH_ERRNO("Failed to create directory "
-                                                "\"%"TS"\"", target);
-                               return WIMLIB_ERR_MKDIR;
-                       }
-               } else {
-                       ERROR_WITH_ERRNO("Failed to stat \"%"TS"\"", target);
-                       return WIMLIB_ERR_STAT;
-               }
-       } else if (!S_ISDIR(stbuf.st_mode)) {
-               ERROR("\"%"TS"\" is not a directory", target);
-               return WIMLIB_ERR_NOTDIR;
-       }
-       return 0;
+       if (!tmkdir(target, 0755))
+               return 0;
+
+       if (errno == EEXIST)
+               return 0;
+
+#ifdef __WIN32__
+       /* _wmkdir() fails with EACCES if called on a drive root directory.  */
+       if (errno == EACCES)
+               return 0;
+#endif
+
+       ERROR_WITH_ERRNO("Failed to create directory \"%"TS"\"", target);
+       return WIMLIB_ERR_MKDIR;
 }
 
 /* Make sure the extraction flags make sense, and update them if needed.  */