Get imagex extract --to-stdout working
authorEric Biggers <ebiggers3@gmail.com>
Sun, 5 May 2013 19:09:18 +0000 (14:09 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 5 May 2013 19:09:58 +0000 (14:09 -0500)
programs/imagex.c
src/extract_image.c
src/util.c
src/wimlib.h

index 071f374..fb2f08b 100644 (file)
@@ -81,6 +81,8 @@ enum imagex_op_type {
 static void usage(int cmd_type);
 static void usage_all();
 
+static bool imagex_be_quiet = false;
+
 
 static const tchar *usage_strings[] = {
 [APPEND] =
@@ -952,6 +954,8 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                     const union wimlib_progress_info *info)
 {
        unsigned percent_done;
+       if (imagex_be_quiet)
+               return 0;
        switch (msg) {
        case WIMLIB_PROGRESS_MSG_WRITE_STREAMS:
                percent_done = TO_PERCENT(info->write_streams.completed_bytes,
@@ -1952,6 +1956,7 @@ imagex_extract(int argc, tchar **argv)
                        break;
                case IMAGEX_TO_STDOUT_OPTION:
                        extract_flags |= WIMLIB_EXTRACT_FLAG_TO_STDOUT;
+                       imagex_be_quiet = true;
                        break;
                default:
                        usage(EXTRACT);
@@ -2006,8 +2011,14 @@ imagex_extract(int argc, tchar **argv)
        ret = wimlib_extract_files(wim, image, 0, cmds, num_cmds,
                                   additional_swms, num_additional_swms,
                                   imagex_progress_func);
-       if (ret == 0)
-               tprintf(T("Done extracting files.\n"));
+       if (ret == 0) {
+               if (!imagex_be_quiet)
+                       tprintf(T("Done extracting files.\n"));
+       } else if (ret == WIMLIB_ERR_PATH_DOES_NOT_EXIST) {
+               tfprintf(stderr, T("Note: You can use `"IMAGEX_PROGNAME" dir' to see what "
+                                  "files and directories\n"
+                                  "      are in the WIM image.\n"));
+       }
 #ifdef __WIN32__
        win32_release_restore_privileges();
 #endif
index 69a4b9e..f6bca15 100644 (file)
@@ -863,6 +863,33 @@ sort_stream_list_by_wim_position(struct list_head *stream_list)
        return 0;
 }
 
+/*
+ * Extract a dentry to standard output.
+ *
+ * This obviously doesn't make sense in all cases.  We return an error if the
+ * dentry does not correspond to a regular file.  Otherwise we extract the
+ * unnamed data stream only.
+ */
+static int
+extract_dentry_to_stdout(struct wim_dentry *dentry)
+{
+       int ret = 0;
+       if (!dentry_is_regular_file(dentry)) {
+               ERROR("\"%"TS"\" is not a regular file and therefore cannot be "
+                     "extracted to standard output", dentry->_full_path);
+               ret = WIMLIB_ERR_NOT_A_REGULAR_FILE;
+       } else {
+               struct wim_lookup_table_entry *lte;
+
+               lte = inode_unnamed_lte_resolved(dentry->d_inode);
+               if (lte) {
+                       ret = extract_wim_resource_to_fd(lte, STDOUT_FILENO,
+                                                        wim_resource_size(lte));
+               }
+       }
+       return ret;
+}
+
 /*
  * extract_tree - Extract a file or directory tree from the currently selected
  *               WIM image.
@@ -951,6 +978,11 @@ extract_tree(WIMStruct *wim, const tchar *wim_source_path, const tchar *target,
        }
        args.extract_root = root;
 
+       ret = calculate_dentry_tree_full_paths(root);
+       if (ret)
+               goto out_ntfs_umount;
+
+
        /* Build a list of the streams that need to be extracted */
        find_streams_for_extraction(root,
                                    &stream_list,
@@ -960,6 +992,11 @@ extract_tree(WIMStruct *wim, const tchar *wim_source_path, const tchar *target,
        calculate_bytes_to_extract(&stream_list, extract_flags,
                                   &args.progress);
 
+       if (extract_flags & WIMLIB_EXTRACT_FLAG_TO_STDOUT) {
+               ret = extract_dentry_to_stdout(root);
+               goto out_mark_inodes_unvisited;
+       }
+
        if (progress_func) {
                progress_func(*wim_source_path ? WIMLIB_PROGRESS_MSG_EXTRACT_TREE_BEGIN :
                              WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN,
@@ -982,10 +1019,6 @@ extract_tree(WIMStruct *wim, const tchar *wim_source_path, const tchar *target,
                              &args.progress);
        }
 
-       ret = calculate_dentry_tree_full_paths(root);
-       if (ret)
-               goto out_mark_inodes_unvisited;
-
        /* Make the directory structure and extract empty files */
        args.extract_flags |= WIMLIB_EXTRACT_FLAG_NO_STREAMS;
        args.apply_dentry = ops->apply_dentry;
index 35fbf6f..901d89c 100644 (file)
@@ -339,6 +339,9 @@ static const tchar *error_strings[] = {
        [WIMLIB_ERR_NOT_A_WIM_FILE]
                = T("The file did not begin with the magic characters that "
                        "identify a WIM file"),
+       [WIMLIB_ERR_NOT_A_REGULAR_FILE]
+               = T("One of the specified paths to extract did not "
+                   "correspond to a regular file"),
        [WIMLIB_ERR_NO_FILENAME]
                = T("The WIM is not identified with a filename"),
        [WIMLIB_ERR_NTFS_3G]
index c497945..b522c68 100644 (file)
@@ -977,6 +977,7 @@ enum wimlib_error_code {
        WIMLIB_ERR_WRITE,
        WIMLIB_ERR_XML,
        WIMLIB_ERR_PATH_DOES_NOT_EXIST,
+       WIMLIB_ERR_NOT_A_REGULAR_FILE,
 };