diff options
-rw-r--r-- | Source/cmSystemTools.cxx | 130 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 5 | ||||
-rw-r--r-- | Source/cmake.cxx | 51 |
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; } |