diff options
author | Brad King <brad.king@kitware.com> | 2019-05-24 14:41:43 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-05-24 14:43:14 (GMT) |
commit | 4ec2b999414495ae58871755307ea17f391f7910 (patch) | |
tree | 3d69527e6968df26a444888fbf09c8c8e7e35bb6 /Source | |
parent | 2b8e5a3ba772d6df6e56a28d8645127008636b03 (diff) | |
parent | c8e217e0a70f8f445e2c593f44e1105c959fb9d7 (diff) | |
download | CMake-4ec2b999414495ae58871755307ea17f391f7910.zip CMake-4ec2b999414495ae58871755307ea17f391f7910.tar.gz CMake-4ec2b999414495ae58871755307ea17f391f7910.tar.bz2 |
Merge topic 'selective-tar-extracting-and-listing'
c8e217e0a7 cmake: tar: Allow selective extracting and listing of archives
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3342
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmSystemTools.cxx | 59 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 6 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 4 |
3 files changed, 60 insertions, 9 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 612284a..2453aea 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1757,7 +1757,9 @@ bool copy_data(struct archive* ar, struct archive* aw) # endif } -bool extract_tar(const char* outFileName, bool verbose, bool extract) +bool extract_tar(const char* outFileName, + const std::vector<std::string>& files, bool verbose, + bool extract) { cmLocaleRAII localeRAII; static_cast<void>(localeRAII); @@ -1766,6 +1768,21 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) archive_read_support_filter_all(a); archive_read_support_format_all(a); struct archive_entry* entry; + + struct archive* matching = archive_match_new(); + if (matching == nullptr) { + cmSystemTools::Error("Out of memory"); + return false; + } + + for (const auto& filename : files) { + if (archive_match_include_pattern(matching, filename.c_str()) != + ARCHIVE_OK) { + cmSystemTools::Error("Failed to add to inclusion list: " + filename); + return false; + } + } + int r = cm_archive_read_open_file(a, outFileName, 10240); if (r) { ArchiveError("Problem with archive_read_open_file(): ", a); @@ -1782,6 +1799,11 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) ArchiveError("Problem with archive_read_next_header(): ", a); break; } + + if (archive_match_excluded(matching, entry)) { + continue; + } + if (verbose) { if (extract) { cmSystemTools::Stdout("x "); @@ -1827,6 +1849,27 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) } } } + + bool error_occured = false; + if (matching != nullptr) { + const char* p; + int ar; + + while ((ar = archive_match_path_unmatched_inclusions_next(matching, &p)) == + ARCHIVE_OK) { + cmSystemTools::Error("tar: " + std::string(p) + + ": Not found in archive"); + error_occured = true; + } + if (error_occured) { + return false; + } + if (ar == ARCHIVE_FATAL) { + cmSystemTools::Error("tar: Out of memory"); + return false; + } + } + archive_match_free(matching); archive_write_free(ext); archive_read_close(a); archive_read_free(a); @@ -1835,23 +1878,29 @@ bool extract_tar(const char* outFileName, bool verbose, bool extract) } #endif -bool cmSystemTools::ExtractTar(const char* outFileName, bool verbose) +bool cmSystemTools::ExtractTar(const char* outFileName, + const std::vector<std::string>& files, + bool verbose) { #if defined(CMAKE_BUILD_WITH_CMAKE) - return extract_tar(outFileName, verbose, true); + return extract_tar(outFileName, files, verbose, true); #else (void)outFileName; + (void)files; (void)verbose; return false; #endif } -bool cmSystemTools::ListTar(const char* outFileName, bool verbose) +bool cmSystemTools::ListTar(const char* outFileName, + const std::vector<std::string>& files, + bool verbose) { #if defined(CMAKE_BUILD_WITH_CMAKE) - return extract_tar(outFileName, verbose, false); + return extract_tar(outFileName, files, verbose, false); #else (void)outFileName; + (void)files; (void)verbose; return false; #endif diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 80c6ee3..09a4d13 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -450,13 +450,15 @@ public: TarCompressNone }; - static bool ListTar(const char* outFileName, bool verbose); + static bool ListTar(const char* outFileName, + const std::vector<std::string>& files, bool verbose); static bool CreateTar(const char* outFileName, const std::vector<std::string>& files, cmTarCompression compressType, bool verbose, std::string const& mtime = std::string(), std::string const& format = std::string()); - static bool ExtractTar(const char* inFileName, bool verbose); + static bool ExtractTar(const char* inFileName, + const std::vector<std::string>& files, bool verbose); // This should be called first thing in main // it will keep child processes from inheriting the // stdin and stdout of this process. This is important diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index ad34107..4ddfddd 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1127,7 +1127,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 1; } if (action == cmSystemTools::TarActionList) { - if (!cmSystemTools::ListTar(outFile.c_str(), verbose)) { + if (!cmSystemTools::ListTar(outFile.c_str(), files, verbose)) { cmSystemTools::Error("Problem listing tar: " + outFile); return 1; } @@ -1142,7 +1142,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 1; } } else if (action == cmSystemTools::TarActionExtract) { - if (!cmSystemTools::ExtractTar(outFile.c_str(), verbose)) { + if (!cmSystemTools::ExtractTar(outFile.c_str(), files, verbose)) { cmSystemTools::Error("Problem extracting tar: " + outFile); return 1; } |