summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmSystemTools.cxx130
-rw-r--r--Source/cmSystemTools.h5
-rw-r--r--Source/cmake.cxx51
3 files changed, 159 insertions, 27 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index df80b9a..91af585 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1363,23 +1363,72 @@ bool cmSystemTools::IsPathToFramework(const char* path)
# include <libtar/libtar.h>
# include <memory> // auto_ptr
# include <fcntl.h>
+# include <cmzlib/zlib.h>
+
+static int gzopen_frontend(char *pathname, int oflags, int mode)
+{
+ char *gzoflags;
+ gzFile gzf;
+ int fd;
+
+ switch (oflags & O_ACCMODE)
+ {
+ case O_WRONLY:
+ gzoflags = "wb";
+ break;
+ case O_RDONLY:
+ gzoflags = "rb";
+ break;
+ default:
+ case O_RDWR:
+ errno = EINVAL;
+ return -1;
+ }
+
+ fd = open(pathname, oflags, mode);
+ if (fd == -1)
+ {
+ return -1;
+ }
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ if ((oflags & O_CREAT) && fchmod(fd, mode))
+ {
+ return -1;
+ }
+#endif
+
+ gzf = gzdopen(fd, gzoflags);
+ if (!gzf)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ return (int)gzf;
+}
+
#endif
-bool cmSystemTools::CreateTar(const char* outFileName, const std::vector<cmStdString>& files)
+bool cmSystemTools::CreateTar(const char* outFileName, const std::vector<cmStdString>& files, bool gzip, bool verbose)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
TAR *t;
char buf[TAR_MAXPATHLEN];
char pathname[TAR_MAXPATHLEN];
+ tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose,
+ (readfunc_t) gzread, (writefunc_t) gzwrite
+ };
+
// Ok, this libtar is not const safe. for now use auto_ptr hack
char* realName = new char[ strlen(outFileName) + 1 ];
std::auto_ptr<char> realNamePtr(realName);
strcpy(realName, outFileName);
if (tar_open(&t, realName,
- NULL,
+ (gzip? &gztype : NULL),
O_WRONLY | O_CREAT, 0644,
- TAR_VERBOSE
+ (verbose?TAR_VERBOSE:0)
| 0) == -1)
{
cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
@@ -1422,22 +1471,28 @@ bool cmSystemTools::CreateTar(const char* outFileName, const std::vector<cmStdSt
#endif
}
-bool cmSystemTools::ExtractTar(const char* outFileName, const std::vector<cmStdString>& files)
+bool cmSystemTools::ExtractTar(const char* outFileName, const std::vector<cmStdString>& files, bool gzip, bool verbose)
{
+ (void)files;
#if defined(CMAKE_BUILD_WITH_CMAKE)
TAR *t;
+
+ tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose,
+ (readfunc_t) gzread, (writefunc_t) gzwrite
+ };
+
// Ok, this libtar is not const safe. for now use auto_ptr hack
char* realName = new char[ strlen(outFileName) + 1 ];
std::auto_ptr<char> realNamePtr(realName);
strcpy(realName, outFileName);
if (tar_open(&t, realName,
- NULL,
+ (gzip? &gztype : NULL),
O_RDONLY
#ifdef _WIN32
| O_BINARY
#endif
, 0,
- TAR_VERBOSE
+ (verbose?TAR_VERBOSE:0)
| 0) == -1)
{
cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
@@ -1460,3 +1515,66 @@ bool cmSystemTools::ExtractTar(const char* outFileName, const std::vector<cmStdS
return false;
#endif
}
+
+bool cmSystemTools::ListTar(const char* outFileName, std::vector<cmStdString>& files, bool gzip, bool verbose)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ TAR *t;
+
+ tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose,
+ (readfunc_t) gzread, (writefunc_t) gzwrite
+ };
+
+ // Ok, this libtar is not const safe. for now use auto_ptr hack
+ char* realName = new char[ strlen(outFileName) + 1 ];
+ std::auto_ptr<char> realNamePtr(realName);
+ strcpy(realName, outFileName);
+ if (tar_open(&t, realName,
+ (gzip? &gztype : NULL),
+ O_RDONLY
+#ifdef _WIN32
+ | O_BINARY
+#endif
+ , 0,
+ (verbose?TAR_VERBOSE:0)
+ | 0) == -1)
+ {
+ cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
+ return false;
+ }
+
+ int i;
+ while ((i = th_read(t)) == 0)
+ {
+ const char* filename = th_get_pathname(t);
+ files.push_back(filename);
+
+ if ( verbose )
+ {
+ th_print_long_ls(t);
+ }
+ else
+ {
+ std::cout << filename << std::endl;
+ }
+
+#ifdef DEBUG
+ th_print(t);
+#endif
+ if (TH_ISREG(t) && tar_skip_regfile(t) != 0)
+ {
+ cmSystemTools::Error("Problem with tar_skip_regfile(): ", strerror(errno));
+ return false;
+ }
+ }
+
+ if (tar_close(t) != 0)
+ {
+ cmSystemTools::Error("Problem with tar_close(): ", strerror(errno));
+ return false;
+ }
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 3103300..181d513 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -298,8 +298,9 @@ public:
static bool PutEnv(const char* value);
/** Create tar */
- static bool CreateTar(const char* outFileName, const std::vector<cmStdString>& files);
- static bool ExtractTar(const char* inFileName, const std::vector<cmStdString>& files);
+ static bool ListTar(const char* outFileName, std::vector<cmStdString>& files, bool gzip, bool verbose);
+ static bool CreateTar(const char* outFileName, const std::vector<cmStdString>& files, bool gzip, bool verbose);
+ static bool ExtractTar(const char* inFileName, const std::vector<cmStdString>& files, bool gzip, bool verbose);
private:
static bool s_ForceUnixPaths;
static bool s_RunCommandHideConsole;
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 0d9de9f..b13ca0f 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -720,8 +720,7 @@ void CMakeCommandUsage(const char* program)
<< " copy_directory source destination - copy directory 'source' content to directory 'destination'\n"
<< " echo [string]... - displays arguments as text\n"
<< " remove file1 file2 ... - remove the file(s)\n"
- << " tar file.tar file/dir1 file/dir2 ... - create a tar\n"
- << " untar file.tar - create a tar\n"
+ << " tar [cxt][vfz] file.tar file/dir1 file/dir2 ... - create a tar.\n"
<< " time command [args] ... - run command and return elapsed time\n";
#if defined(_WIN32) && !defined(__CYGWIN__)
errorStream
@@ -949,33 +948,47 @@ int cmake::CMakeCommand(std::vector<std::string>& args)
// Tar files
else if (args[1] == "tar" && args.size() > 3)
{
- std::string outFile = args[2];
+ std::string flags = args[2];
+ std::string outFile = args[3];
std::vector<cmStdString> files;
- for (std::string::size_type cc = 3; cc < args.size(); cc ++)
+ for (std::string::size_type cc = 4; cc < args.size(); cc ++)
{
files.push_back(args[cc]);
}
- if ( !cmSystemTools::CreateTar(outFile.c_str(), files) )
+ bool gzip = false;
+ bool verbose = false;
+ if ( flags.find_first_of('z') != flags.npos )
{
- cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
- return 1;
+ gzip = true;
+ }
+ if ( flags.find_first_of('v') != flags.npos )
+ {
+ verbose = true;
}
- return 0;
- }
- // Untar files
- else if (args[1] == "untar" && args.size() > 2)
- {
- std::string outFile = args[2];
- std::vector<cmStdString> files;
- for (std::string::size_type cc = 3; cc < args.size(); cc ++)
+ if ( flags.find_first_of('t') != flags.npos )
{
- files.push_back(args[cc]);
+ if ( !cmSystemTools::ListTar(outFile.c_str(), files, gzip, verbose) )
+ {
+ cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
+ return 1;
+ }
}
- if ( !cmSystemTools::ExtractTar(outFile.c_str(), files) )
+ else if ( flags.find_first_of('c') != flags.npos )
{
- cmSystemTools::Error("Problem extracting tar: ", outFile.c_str());
- return 1;
+ if ( !cmSystemTools::CreateTar(outFile.c_str(), files, gzip, verbose) )
+ {
+ cmSystemTools::Error("Problem creating tar: ", outFile.c_str());
+ return 1;
+ }
+ }
+ else if ( flags.find_first_of('x') != flags.npos )
+ {
+ if ( !cmSystemTools::ExtractTar(outFile.c_str(), files, gzip, verbose) )
+ {
+ cmSystemTools::Error("Problem extracting tar: ", outFile.c_str());
+ return 1;
+ }
}
return 0;
}