]> wimlib.net Git - wimlib/blobdiff - src/extract.c
do_feature_check(): Tweak warnings
[wimlib] / src / extract.c
index 95071bd7bfbb35b45dec106755a88b1c0db204e8..e599ffffda65cf775c73bd7d40cea424c8543b8b 100644 (file)
@@ -1203,8 +1203,7 @@ extract_stream_list(struct apply_ctx *ctx)
        bool can_seek;
        int ret;
 
-       can_seek = !(lseek(ctx->wim->in_fd.fd, 0, SEEK_CUR) == (off_t)-1 &&
-                    errno == ESPIPE);
+       can_seek = (lseek(ctx->wim->in_fd.fd, 0, SEEK_CUR) != -1);
        list_for_each_entry(lte, &ctx->stream_list, extraction_list) {
                ret = extract_stream_instances(lte, ctx, can_seek);
                if (ret)
@@ -1338,42 +1337,6 @@ dentry_extract_final(struct wim_dentry *dentry, void *_ctx)
        return extract_timestamps(path, ctx, dentry);
 }
 
-/* Sorts a list of streams in ascending order of their offset in the WIM file in
- * order to prepare for sequential extraction.  */
-static int
-sort_stream_list_by_wim_position(struct list_head *stream_list)
-{
-       struct list_head *cur;
-       size_t num_streams;
-       struct wim_lookup_table_entry **array;
-       size_t i;
-       size_t array_size;
-
-       num_streams = 0;
-       list_for_each(cur, stream_list)
-               num_streams++;
-       array_size = num_streams * sizeof(array[0]);
-       array = MALLOC(array_size);
-       if (!array) {
-               ERROR("Failed to allocate %zu bytes to sort stream entries",
-                     array_size);
-               return WIMLIB_ERR_NOMEM;
-       }
-       cur = stream_list->next;
-       for (i = 0; i < num_streams; i++) {
-               array[i] = container_of(cur, struct wim_lookup_table_entry, extraction_list);
-               cur = cur->next;
-       }
-
-       qsort(array, num_streams, sizeof(array[0]), cmp_streams_by_wim_position);
-
-       INIT_LIST_HEAD(stream_list);
-       for (i = 0; i < num_streams; i++)
-               list_add_tail(&array[i]->extraction_list, stream_list);
-       FREE(array);
-       return 0;
-}
-
 /*
  * Extract a WIM dentry to standard output.
  *
@@ -1686,76 +1649,90 @@ static int
 do_feature_check(const struct wim_features *required_features,
                 const struct wim_features *supported_features,
                 int extract_flags,
-                const struct apply_operations *ops)
+                const struct apply_operations *ops,
+                const tchar *wim_source_path)
 {
+       const tchar *loc;
+       const tchar *mode = "this extraction mode";
+
+       if (wim_source_path[0] == '\0')
+               loc = "the WIM image";
+       else
+               loc = wim_source_path;
+
+       /* We're an archive program, so theoretically we can do what we want
+        * with FILE_ATTRIBUTE_ARCHIVE (which is a dumb flag anyway).  Don't
+        * bother the user about it.  */
+#if 0
        if (required_features->archive_files && !supported_features->archive_files)
        {
                WARNING(
-          "%lu files are marked as archived, but this attribute\n"
-"          is not supported in this extraction mode or volume.",
-                       required_features->archive_files);
+          "%lu files in %"TS" are marked as archived, but this attribute\n"
+"          is not supported in %"TS".",
+                       required_features->archive_files, loc, mode);
        }
+#endif
 
        if (required_features->hidden_files && !supported_features->hidden_files)
        {
                WARNING(
-          "%lu files are marked as hidden, but this attribute\n"
-"          is not supported in this extraction mode or volume.",
-                       required_features->hidden_files);
+          "%lu files in %"TS" are marked as hidden, but this\n"
+"          attribute is not supported in %"TS".",
+                       required_features->hidden_files, loc, mode);
        }
 
        if (required_features->system_files && !supported_features->system_files)
        {
                WARNING(
-          "%lu files are marked as system files, but this attribute\n"
-"          is not supported in this extraction mode or volume.",
-                       required_features->system_files);
+          "%lu files in %"TS" are marked as system files,\n"
+"          but this attribute is not supported in %"TS".",
+                       required_features->system_files, loc, mode);
        }
 
        if (required_features->compressed_files && !supported_features->compressed_files)
        {
                WARNING(
-          "%lu files are marked as being transparently compressed, but\n"
-"          transparent compression is not supported in this extraction\n"
-"          mode or volume.  These files will be extracted as uncompressed.",
-                       required_features->compressed_files);
+          "%lu files in %"TS" are marked as being transparently\n"
+"          compressed, but transparent compression is not supported in\n"
+"          %"TS".  These files will be extracted as uncompressed.",
+                       required_features->compressed_files, loc, mode);
        }
 
        if (required_features->encrypted_files && !supported_features->encrypted_files)
        {
                WARNING(
-          "%lu files are marked as being encrypted, but encryption is not\n"
-"          supported in this extraction mode or volume.  These files will be\n"
-"          extracted as raw encrypted data instead.",
-                       required_features->encrypted_files);
+          "%lu files in %"TS" are marked as being encrypted,\n"
+"           but encryption is not supported in %"TS".  These files\n"
+"           will be extracted as raw encrypted data instead.",
+                       required_features->encrypted_files, loc, mode);
        }
 
        if (required_features->not_context_indexed_files &&
            !supported_features->not_context_indexed_files)
        {
                WARNING(
-          "%lu files are marked as not content indexed, but this attribute\n"
-"          is not supported in this extraction mode or volume.",
-                       required_features->not_context_indexed_files);
+          "%lu files in %"TS" are marked as not content indexed,\n"
+"          but this attribute is not supported in %"TS".",
+                       required_features->not_context_indexed_files, loc, mode);
        }
 
        if (required_features->sparse_files && !supported_features->sparse_files)
        {
                WARNING(
-          "%lu files are marked as sparse, but creating sparse files is not\n"
-"          supported in this extraction mode or volume.  These files will be\n"
-"          extracted as non-sparse.",
-                       required_features->not_context_indexed_files);
+          "%lu files in %"TS" are marked as sparse, but creating\n"
+"           sparse files is not supported in %"TS".  These files\n"
+"           will be extracted as non-sparse.",
+                       required_features->sparse_files, loc, mode);
        }
 
        if (required_features->named_data_streams &&
            !supported_features->named_data_streams)
        {
                WARNING(
-          "%lu files contain one or more alternate (named) data streams,\n"
-"          which are not supported in this extraction mode or volume.\n"
+          "%lu files in %"TS" contain one or more alternate (named)\n"
+"          data streams, which are not supported in %"TS".\n"
 "          Alternate data streams will NOT be extracted.",
-                       required_features->named_data_streams);
+                       required_features->named_data_streams, loc, mode);
        }
 
        if (unlikely(extract_flags & (WIMLIB_EXTRACT_FLAG_HARDLINK |
@@ -1764,19 +1741,19 @@ do_feature_check(const struct wim_features *required_features,
            supported_features->named_data_streams)
        {
                WARNING(
-          "%lu files contain one or more alternate (named) data streams,\n"
-"          which are not supported in linked extraction mode.\n"
+          "%lu files in %"TS" contain one or more alternate (named)\n"
+"          data streams, which are not supported in linked extraction mode.\n"
 "          Alternate data streams will NOT be extracted.",
-                       required_features->named_data_streams);
+                       required_features->named_data_streams, loc);
        }
 
        if (required_features->hard_links && !supported_features->hard_links)
        {
                WARNING(
-          "%lu files are hard links, but hard links are not supported in\n"
-"          this extraction mode or volume.  Hard links will be extracted as\n"
+          "%lu files in %"TS" are hard links, but hard links are\n"
+"          not supported in %"TS".  Hard links will be extracted as\n"
 "          duplicate copies of the linked files.",
-                       required_features->hard_links);
+                       required_features->hard_links, loc, mode);
        }
 
        if (required_features->reparse_points && !supported_features->reparse_points)
@@ -1784,16 +1761,17 @@ do_feature_check(const struct wim_features *required_features,
                if (supported_features->symlink_reparse_points) {
                        if (required_features->other_reparse_points) {
                                WARNING(
-          "%lu files are reparse points that are neither symbolic links\n"
-"          nor junction points and are not supported in this extraction mode\n"
-"          or volume.  These reparse points will not be extracted.",
-                                       required_features->other_reparse_points);
+          "%lu files in %"TS" are reparse points that are neither\n"
+"          symbolic links nor junction points and are not supported in\n"
+"          %"TS".  These reparse points will not be extracted.",
+                                       required_features->other_reparse_points, loc,
+                                       mode);
                        }
                } else {
                        WARNING(
-          "%lu files are reparse points, which are not supported in this\n"
-"          extraction mode or volume and will not be extracted.",
-                               required_features->reparse_points);
+          "%lu files in %"TS" are reparse points, which are\n"
+"          not supported in %"TS" and will not be extracted.",
+                               required_features->reparse_points, loc, mode);
                }
        }
 
@@ -1801,40 +1779,37 @@ do_feature_check(const struct wim_features *required_features,
            !supported_features->security_descriptors)
        {
                WARNING(
-          "%lu files have Windows NT security descriptors, but extracting\n"
-"          security descriptors is not supported in this extraction mode\n"
-"          or volume.  No security descriptors will be extracted.",
-                       required_features->security_descriptors);
+          "%lu files in %"TS" have Windows NT security descriptors,\n"
+"          but extracting security descriptors is not supported in\n"
+"          %"TS".  No security descriptors will be extracted.",
+                       required_features->security_descriptors, loc, mode);
        }
 
        if (required_features->short_names && !supported_features->short_names)
        {
                WARNING(
-          "%lu files have short (DOS) names, but extracting short names\n"
-"          is not supported in this extraction mode or volume.  Short names\n"
-"          will not be extracted.\n",
-                       required_features->short_names);
+          "%lu files in %"TS" have short (DOS) names, but\n"
+"          extracting short names is not supported in %"TS".\n"
+"          Short names will not be extracted.\n",
+                       required_features->short_names, loc, mode);
        }
 
        if ((extract_flags & WIMLIB_EXTRACT_FLAG_UNIX_DATA) &&
            required_features->unix_data && !supported_features->unix_data)
        {
-               ERROR("UNIX data not supported in this extraction mode "
-                     "or volume", ops->name);
+               ERROR("Extracting UNIX data is not supported in %"TS, mode);
                return WIMLIB_ERR_UNSUPPORTED;
        }
        if ((extract_flags & WIMLIB_EXTRACT_FLAG_STRICT_SHORT_NAMES) &&
            required_features->short_names && !supported_features->short_names)
        {
-               ERROR("Short names are not supported in this extraction "
-                     "mode or volume", ops->name);
+               ERROR("Extracting short names is not supported in %"TS"", mode);
                return WIMLIB_ERR_UNSUPPORTED;
        }
        if ((extract_flags & WIMLIB_EXTRACT_FLAG_STRICT_TIMESTAMPS) &&
            !ops->set_timestamps)
        {
-               ERROR("Timestamps are not supported in this extraction "
-                     "mode or volume", ops->name);
+               ERROR("Extracting timestamps is not supported in %"TS"", mode);
                return WIMLIB_ERR_UNSUPPORTED;
        }
        if (((extract_flags & (WIMLIB_EXTRACT_FLAG_STRICT_ACLS |
@@ -1843,8 +1818,7 @@ do_feature_check(const struct wim_features *required_features,
            required_features->security_descriptors &&
            !supported_features->security_descriptors)
        {
-               ERROR("Security descriptors not supported in this extraction "
-                     "mode or volume.");
+               ERROR("Extracting security descriptors is not supported in %"TS, mode);
                return WIMLIB_ERR_UNSUPPORTED;
        }
 
@@ -1852,7 +1826,7 @@ do_feature_check(const struct wim_features *required_features,
            !supported_features->hard_links)
        {
                ERROR("Hard link extraction mode requested, but "
-                     "extraction mode or volume does not support hard links!");
+                     "%"TS" does not support hard links!", mode);
                return WIMLIB_ERR_UNSUPPORTED;
        }
 
@@ -1860,8 +1834,8 @@ do_feature_check(const struct wim_features *required_features,
            !supported_features->symlink_reparse_points)
        {
                ERROR("Symbolic link extraction mode requested, but "
-                     "extraction mode or volume does not support symbolic "
-                     "links!");
+                     "%"TS" does not support symbolic "
+                     "links!", mode);
                return WIMLIB_ERR_UNSUPPORTED;
        }
        return 0;
@@ -1975,7 +1949,7 @@ extract_tree(WIMStruct *wim, const tchar *wim_source_path, const tchar *target,
 
        dentry_tree_get_features(root, &required_features);
        ret = do_feature_check(&required_features, &ctx.supported_features,
-                              extract_flags, ctx.ops);
+                              extract_flags, ctx.ops, wim_source_path);
        if (ret)
                goto out_finish_or_abort_extract;
 
@@ -2022,8 +1996,7 @@ extract_tree(WIMStruct *wim, const tchar *wim_source_path, const tchar *target,
         * output.  In that case, "root" should be a single file, not a
         * directory tree.  (If not, extract_dentry_to_stdout() will
         * return an error.)  */
-       if (extract_flags & WIMLIB_EXTRACT_FLAG_TO_STDOUT &&
-           !(extract_flags & WIMLIB_EXTRACT_FLAG_FROM_PIPE)) {
+       if (extract_flags & WIMLIB_EXTRACT_FLAG_TO_STDOUT) {
                ret = extract_dentry_to_stdout(root);
                goto out_teardown_stream_list;
        }
@@ -2035,7 +2008,10 @@ extract_tree(WIMStruct *wim, const tchar *wim_source_path, const tchar *target,
                              WIMLIB_EXTRACT_FLAG_FROM_PIPE))
                                        == WIMLIB_EXTRACT_FLAG_SEQUENTIAL)
        {
-               ret = sort_stream_list_by_wim_position(&ctx.stream_list);
+               ret = sort_stream_list_by_sequential_order(
+                               &ctx.stream_list,
+                               offsetof(struct wim_lookup_table_entry,
+                                        extraction_list));
                if (ret)
                        goto out_teardown_stream_list;
        }
@@ -2276,8 +2252,7 @@ do_wimlib_extract_files(WIMStruct *wim,
                return ret;
 
        /* Make sure there are no streams in the WIM that have not been
-        * checksummed yet.  Needed at least because 'unhashed_list' aliases
-        * 'extraction_list' in `struct wim_lookup_table_entry'.  */
+        * checksummed yet.  */
        ret = wim_checksum_unhashed_streams(wim);
        if (ret)
                return ret;
@@ -2461,12 +2436,10 @@ extract_all_images(WIMStruct *wim,
 
        extract_flags |= WIMLIB_EXTRACT_FLAG_MULTI_IMAGE;
 
-#ifdef WITH_NTFS_3G
        if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
                ERROR("Cannot extract multiple images in NTFS extraction mode.");
                return WIMLIB_ERR_INVALID_PARAM;
        }
-#endif
 
        if (tstat(target, &stbuf)) {
                if (errno == ENOENT) {
@@ -2629,16 +2602,26 @@ wimlib_extract_image_from_pipe(int pipe_fd, const tchar *image_num_or_name,
 
        /* Get image index (this may use the XML data that was just read to
         * resolve an image name).  */
-       image = wimlib_resolve_image(pwm, image_num_or_name);
-       if (image == WIMLIB_NO_IMAGE) {
-               ERROR("\"%"TS"\" is not a valid image in the pipable WIM!",
-                     image_num_or_name);
-               ret = WIMLIB_ERR_INVALID_IMAGE;
-               goto out_wimlib_free;
-       } else if (image == WIMLIB_ALL_IMAGES) {
-               ERROR("Applying all images from a pipe is not supported.");
-               ret = WIMLIB_ERR_INVALID_IMAGE;
-               goto out_wimlib_free;
+       if (image_num_or_name) {
+               image = wimlib_resolve_image(pwm, image_num_or_name);
+               if (image == WIMLIB_NO_IMAGE) {
+                       ERROR("\"%"TS"\" is not a valid image in the pipable WIM!",
+                             image_num_or_name);
+                       ret = WIMLIB_ERR_INVALID_IMAGE;
+                       goto out_wimlib_free;
+               } else if (image == WIMLIB_ALL_IMAGES) {
+                       ERROR("Applying all images from a pipe is not supported.");
+                       ret = WIMLIB_ERR_INVALID_IMAGE;
+                       goto out_wimlib_free;
+               }
+       } else {
+               if (pwm->hdr.image_count != 1) {
+                       ERROR("No image was specified, but the pipable WIM "
+                             "did not contain exactly 1 image");
+                       ret = WIMLIB_ERR_INVALID_IMAGE;
+                       goto out_wimlib_free;
+               }
+               image = 1;
        }
 
        /* Load the needed metadata resource.  */