summaryrefslogtreecommitdiffstats
path: root/Source/cmSystemTools.cxx
diff options
context:
space:
mode:
authorBartosz Kosiorek <gang65@poczta.onet.pl>2019-05-22 19:29:08 (GMT)
committerBrad King <brad.king@kitware.com>2019-05-23 14:08:22 (GMT)
commitc8e217e0a70f8f445e2c593f44e1105c959fb9d7 (patch)
treeb02a243d33320167c75705eb7f332bb419352eb4 /Source/cmSystemTools.cxx
parentf03a80aefd4073bc1502c2e486fedfdbd8addfb6 (diff)
downloadCMake-c8e217e0a70f8f445e2c593f44e1105c959fb9d7.zip
CMake-c8e217e0a70f8f445e2c593f44e1105c959fb9d7.tar.gz
CMake-c8e217e0a70f8f445e2c593f44e1105c959fb9d7.tar.bz2
cmake: tar: Allow selective extracting and listing of archives
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r--Source/cmSystemTools.cxx59
1 files changed, 54 insertions, 5 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 6359d60..d00d4d0 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