]> wimlib.net Git - wimlib/blobdiff - src/extract.c
wimlib_extract_flags(): Free memory used in linked extraction mode
[wimlib] / src / extract.c
index abce21f030f0c7776d49f2f4e1ff27aba5e9ceb6..44076db02b58e4ecef6da9d617c51005d4f720e7 100644 (file)
@@ -1530,8 +1530,8 @@ extract_streams_from_pipe(struct apply_ctx *ctx)
                                if (ret)
                                        goto out_free_found_lte;
 
-                               ret = extract_stream_to_fd(needed_lte, &tmpfile_fd,
-                                                          needed_lte->size);
+                               ret = extract_full_stream_to_fd(needed_lte,
+                                                               &tmpfile_fd);
                                if (ret) {
                                        filedes_close(&tmpfile_fd);
                                        goto delete_tmpfile;
@@ -1651,7 +1651,7 @@ extract_dentry_to_stdout(struct wim_dentry *dentry)
                if (lte) {
                        struct filedes _stdout;
                        filedes_init(&_stdout, STDOUT_FILENO);
-                       ret = extract_stream_to_fd(lte, &_stdout, lte->size);
+                       ret = extract_full_stream_to_fd(lte, &_stdout);
                }
        }
        return ret;
@@ -2391,9 +2391,12 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
        }
 
        if (progress_func) {
-               progress_func(*wim_source_path ? WIMLIB_PROGRESS_MSG_EXTRACT_TREE_BEGIN :
-                                                WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN,
-                             &ctx.progress);
+               int msg;
+               if (*wim_source_path || (extract_flags & WIMLIB_EXTRACT_FLAG_PATHMODE))
+                       msg = WIMLIB_PROGRESS_MSG_EXTRACT_TREE_BEGIN;
+               else
+                       msg = WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN;
+               progress_func(msg, &ctx.progress);
        }
 
        if (!ctx.root_dentry_is_special)
@@ -2500,9 +2503,12 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
                goto out_free_realtarget;
 
        if (progress_func) {
-               progress_func(*wim_source_path ? WIMLIB_PROGRESS_MSG_EXTRACT_TREE_END :
-                             WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END,
-                             &ctx.progress);
+               int msg;
+               if (*wim_source_path || (extract_flags & WIMLIB_EXTRACT_FLAG_PATHMODE))
+                       msg = WIMLIB_PROGRESS_MSG_EXTRACT_TREE_END;
+               else
+                       msg = WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END;
+               progress_func(msg, &ctx.progress);
        }
 
        do_extract_warnings(&ctx);
@@ -2586,19 +2592,12 @@ extract_tree(WIMStruct *wim, const tchar *wim_source_path,
                             target, extract_flags, progress_func);
 }
 
-/* Validates a single wimlib_extract_command, mostly checking to make sure the
- * extract flags make sense. */
+/* Make sure the extraction flags make sense, and update them if needed.  */
 static int
-check_extract_command(struct wimlib_extract_command *cmd, int wim_header_flags)
+check_extract_flags(int extract_flags,
+                   const u32 wim_header_flags,
+                   int *updated_extract_flags_ret)
 {
-       int extract_flags;
-
-       /* Empty destination path? */
-       if (cmd->fs_dest_path[0] == T('\0'))
-               return WIMLIB_ERR_INVALID_PARAM;
-
-       extract_flags = cmd->extract_flags;
-
        /* Check for invalid flag combinations  */
        if ((extract_flags &
             (WIMLIB_EXTRACT_FLAG_SYMLINK |
@@ -2606,9 +2605,6 @@ check_extract_command(struct wimlib_extract_command *cmd, int wim_header_flags)
                                                 WIMLIB_EXTRACT_FLAG_HARDLINK))
                return WIMLIB_ERR_INVALID_PARAM;
 
-       if (extract_flags & WIMLIB_EXTRACT_FLAG_GLOB_PATHS)
-               return WIMLIB_ERR_INVALID_PARAM;
-
        if ((extract_flags &
             (WIMLIB_EXTRACT_FLAG_NO_ACLS |
              WIMLIB_EXTRACT_FLAG_STRICT_ACLS)) == (WIMLIB_EXTRACT_FLAG_NO_ACLS |
@@ -2626,13 +2622,13 @@ check_extract_command(struct wimlib_extract_command *cmd, int wim_header_flags)
              WIMLIB_EXTRACT_FLAG_FROM_PIPE)) == WIMLIB_EXTRACT_FLAG_RESUME)
                return WIMLIB_ERR_INVALID_PARAM;
 
-       if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
 #ifndef WITH_NTFS_3G
+       if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
                ERROR("wimlib was compiled without support for NTFS-3g, so\n"
                      "        we cannot apply a WIM image directly to a NTFS volume.");
                return WIMLIB_ERR_UNSUPPORTED;
-#endif
        }
+#endif
 
        if ((extract_flags & (WIMLIB_EXTRACT_FLAG_RPFIX |
                              WIMLIB_EXTRACT_FLAG_NORPFIX)) == 0)
@@ -2663,7 +2659,8 @@ check_extract_command(struct wimlib_extract_command *cmd, int wim_header_flags)
                }
        }
 
-       cmd->extract_flags = extract_flags;
+       if (updated_extract_flags_ret)
+               *updated_extract_flags_ret = extract_flags;
        return 0;
 }
 
@@ -2694,7 +2691,16 @@ do_wimlib_extract_files(WIMStruct *wim,
 
        /* Check for problems with the extraction commands */
        for (size_t i = 0; i < num_cmds; i++) {
-               ret = check_extract_command(&cmds[i], wim->hdr.flags);
+
+               if (cmds[i].fs_dest_path[0] == T('\0'))
+                       return WIMLIB_ERR_INVALID_PARAM;
+
+               if (cmds[i].extract_flags & WIMLIB_EXTRACT_FLAG_GLOB_PATHS)
+                       return WIMLIB_ERR_INVALID_PARAM;
+
+               ret = check_extract_flags(cmds[i].extract_flags,
+                                         wim->hdr.flags,
+                                         &cmds[i].extract_flags);
                if (ret)
                        return ret;
                if (cmds[i].extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK |
@@ -3111,8 +3117,11 @@ wimlib_extract_pathlist(WIMStruct *wim, int image,
        void *mem;
 
        ret = read_path_list_file(path_list_file, &paths, &num_paths, &mem);
-       if (ret)
+       if (ret) {
+               ERROR("Failed to read path list file \"%"TS"\"",
+                     path_list_file);
                return ret;
+       }
 
        ret = wimlib_extract_paths(wim, image, target,
                                   (const tchar * const *)paths, num_paths,
@@ -3171,9 +3180,15 @@ wimlib_extract_paths(WIMStruct *wim,
 
        extract_flags &= WIMLIB_EXTRACT_MASK_PUBLIC;
 
-       if (target == NULL || (num_paths != 0 && paths == NULL))
+       if (wim == NULL || target == NULL || target[0] == T('\0') ||
+           (num_paths != 0 && paths == NULL))
                return WIMLIB_ERR_INVALID_PARAM;
 
+       ret = check_extract_flags(extract_flags, wim->hdr.flags,
+                                 &extract_flags);
+       if (ret)
+               return ret;
+
        ret = select_wim_image(wim, image);
        if (ret)
                return ret;
@@ -3231,6 +3246,14 @@ wimlib_extract_paths(WIMStruct *wim,
                                ~WIMLIB_EXTRACT_FLAG_GLOB_PATHS)
                                | WIMLIB_EXTRACT_FLAG_PATHMODE),
                            progress_func);
+
+       if (extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK |
+                            WIMLIB_EXTRACT_FLAG_HARDLINK))
+       {
+               for_lookup_table_entry(wim->lookup_table,
+                                      lte_free_extracted_file,
+                                      NULL);
+       }
 out_free_trees:
        FREE(trees);
        return ret;