From e5c13f94058aedcea95236a9728093fa283d49b3 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 5 May 2013 14:09:18 -0500 Subject: [PATCH] Get imagex extract --to-stdout working --- programs/imagex.c | 15 +++++++++++++-- src/extract_image.c | 41 +++++++++++++++++++++++++++++++++++++---- src/util.c | 3 +++ src/wimlib.h | 1 + 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/programs/imagex.c b/programs/imagex.c index 071f3749..fb2f08b7 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -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 diff --git a/src/extract_image.c b/src/extract_image.c index 69a4b9e8..f6bca157 100644 --- a/src/extract_image.c +++ b/src/extract_image.c @@ -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; diff --git a/src/util.c b/src/util.c index 35fbf6f1..901d89ca 100644 --- a/src/util.c +++ b/src/util.c @@ -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] diff --git a/src/wimlib.h b/src/wimlib.h index c4979458..b522c687 100644 --- a/src/wimlib.h +++ b/src/wimlib.h @@ -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, }; -- 2.43.0