summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt5
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx230
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.h47
-rw-r--r--Source/CPack/cmCPackTGZGenerator.cxx272
-rw-r--r--Source/CPack/cmCPackTGZGenerator.h18
-rw-r--r--Source/CPack/cmCPackTarBZip2Generator.cxx156
-rw-r--r--Source/CPack/cmCPackTarBZip2Generator.h14
-rw-r--r--Source/CPack/cmCPackTarCompressGenerator.cxx231
-rw-r--r--Source/CPack/cmCPackTarCompressGenerator.h12
-rw-r--r--Source/CPack/cmCPackZIPGenerator.cxx76
-rw-r--r--Source/CPack/cmCPackZIPGenerator.h14
-rw-r--r--Source/cmSystemTools.cxx567
12 files changed, 615 insertions, 1027 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 9099691..96b0e4e 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -325,10 +325,10 @@ ENDIF (WIN32)
# create a library used by the command line and the GUI
ADD_LIBRARY(CMakeLib ${SRCS})
-TARGET_LINK_LIBRARIES(CMakeLib cmsys
+TARGET_LINK_LIBRARIES(CMakeLib cmsys
${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES}
${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES}
- ${CMAKE_CURL_LIBRARIES})
+ ${CMAKE_CURL_LIBRARIES} )
# On Apple we need Carbon
IF(APPLE)
@@ -405,6 +405,7 @@ TARGET_LINK_LIBRARIES(CTestLib CMakeLib ${CMAKE_CURL_LIBRARIES} ${CMAKE_XMLRPC_L
# Sources for CPack
#
SET(CPACK_SRCS
+ CPack/cmCPackArchiveGenerator.cxx
CPack/cmCPackComponentGroup.cxx
CPack/cmCPackGeneratorFactory.cxx
CPack/cmCPackGenerator.cxx
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
new file mode 100644
index 0000000..b11670c
--- /dev/null
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -0,0 +1,230 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmCPackArchiveGenerator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackLog.h"
+#include <errno.h>
+
+#include <cmsys/SystemTools.hxx>
+#include <cmlibarchive/libarchive/archive.h>
+#include <cmlibarchive/libarchive/archive_entry.h>
+
+
+//----------------------------------------------------------------------
+cmCPackArchiveGenerator::cmCPackArchiveGenerator(CompressType t,
+ ArchiveType at)
+{
+ this->Compress = t;
+ this->Archive = at;
+}
+
+//----------------------------------------------------------------------
+cmCPackArchiveGenerator::~cmCPackArchiveGenerator()
+{
+}
+
+static const size_t cmCPackTGZ_Data_BlockSize = 16384;
+
+// make this an anonymous namespace so that archive.h does not
+// have to be included in the .h file for this class
+namespace
+{
+bool SetArchiveType(struct archive* a,
+ cmCPackArchiveGenerator::CompressType ct,
+ cmCPackArchiveGenerator::ArchiveType at)
+{
+ // pick a compression type
+ int res;
+ switch(ct)
+ {
+ case cmCPackArchiveGenerator::GZIP:
+ res = archive_write_set_compression_gzip(a);
+ break;
+ case cmCPackArchiveGenerator::BZIP2:
+ res = archive_write_set_compression_bzip2(a);
+ break;
+ case cmCPackArchiveGenerator::COMPRESS:
+ res = archive_write_set_compression_compress(a);
+ break;
+ case cmCPackArchiveGenerator::LZMA:
+ res = archive_write_set_compression_lzma(a);
+ break;
+ case cmCPackArchiveGenerator::NONE:
+ default:
+ res = archive_write_set_compression_none(a);
+ }
+ if(res != ARCHIVE_OK)
+ {
+ return false;
+ }
+ // pick the archive type
+ switch(at)
+ {
+ case cmCPackArchiveGenerator::TAR:
+ // maybe this:
+ // archive_write_set_format_pax(a);
+ res = archive_write_set_format_ustar(a); // is this what we want?
+ break;
+ case cmCPackArchiveGenerator::ZIP:
+ res = archive_write_set_format_zip(a);
+ break;
+ }
+ if(res != ARCHIVE_OK)
+ {
+ return false;
+ }
+ return true;
+}
+
+struct StreamData
+{
+ StreamData(cmGeneratedFileStream* gfs,
+ cmCPackArchiveGenerator* ag)
+ {
+ this->GeneratedFileStream = gfs;
+ this->Generator = ag;
+ }
+ cmGeneratedFileStream* GeneratedFileStream;
+ cmCPackArchiveGenerator* Generator;
+};
+
+
+extern "C"
+{
+int OpenArchive(struct archive *a, void *client_data)
+{
+ struct StreamData *data = (StreamData*)client_data;
+ if(data->GeneratedFileStream &&
+ data->GeneratedFileStream->is_open())
+ {
+ if(data->Generator->
+ GenerateHeader(data->GeneratedFileStream))
+ {
+ return ARCHIVE_OK;
+ }
+ }
+ return (ARCHIVE_FATAL);
+}
+
+__LA_SSIZE_T WriteArchive(struct archive *a,
+ void *client_data,
+ const void *buff,
+ size_t n)
+{
+ struct StreamData *data = (StreamData*)client_data;
+ data->GeneratedFileStream->
+ write(reinterpret_cast<const char*>(buff),n);
+ if(!data->GeneratedFileStream->bad())
+ {
+ return n;
+ }
+ return 0;
+}
+
+
+int CloseArchive(struct archive *a, void *client_data)
+{
+ struct StreamData *data = (StreamData*)client_data;
+ if(data->GeneratedFileStream->Close())
+ {
+ delete data->GeneratedFileStream;
+ return ARCHIVE_OK;
+ }
+ return ARCHIVE_FATAL;
+}
+} //extern C
+} // anon name space
+
+
+//----------------------------------------------------------------------
+int cmCPackArchiveGenerator::InitializeInternal()
+{
+ this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
+ return this->Superclass::InitializeInternal();
+}
+
+int cmCPackArchiveGenerator::CompressFiles(const char* outFileName,
+ const char* toplevel, const std::vector<std::string>& files)
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
+ << (toplevel ? toplevel : "(NULL)") << std::endl);
+ // create a new archive
+ struct archive* a = archive_write_new();
+ // Set the compress and archive types for the archive
+ SetArchiveType(a, this->Compress, this->Archive);
+ // Open binary stream
+ cmGeneratedFileStream* gf = new cmGeneratedFileStream;
+ gf->Open(outFileName, false, true);
+ StreamData data(gf, this);
+ // pass callbacks to archive_write_open to handle stream
+ archive_write_open(a,
+ &data,
+ OpenArchive,
+ WriteArchive,
+ CloseArchive);
+ // create a new disk struct
+ struct archive* disk = archive_read_disk_new();
+ archive_read_disk_set_standard_lookup(disk);
+ std::vector<std::string>::const_iterator fileIt;
+ for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
+ {
+ // create a new entry for each file
+ struct archive_entry *entry = archive_entry_new();
+ // Get the relative path to the file
+ std::string rp = cmSystemTools::RelativePath(toplevel, fileIt->c_str());
+ // Set the name of the entry to the file name
+ archive_entry_set_pathname(entry, rp.c_str());
+ // get the information about the file from stat
+ struct stat s;
+ stat(fileIt->c_str(), &s);
+ archive_read_disk_entry_from_file(disk, entry, -1, &s);
+ // write entry header
+ archive_write_header(a, entry);
+ // now copy contents of file into archive a
+ FILE* file = fopen(fileIt->c_str(), "rb");
+ if(!file)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with fopen(): "
+ << file
+ << strerror(errno)
+ << std::endl);
+ return 0;
+ }
+ char buff[cmCPackTGZ_Data_BlockSize];
+ int len = fread(buff, 1, sizeof(buff), file);
+ while (len > 0)
+ {
+ archive_write_data(a, buff, len);
+ len = fread(buff, 1, sizeof(buff), file);
+ }
+ // close the file and free the entry
+ fclose(file);
+ archive_entry_free(entry);
+ }
+ // close the archive and finish the write
+ archive_write_close(a);
+ archive_write_finish(a);
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackArchiveGenerator::GenerateHeader(std::ostream*)
+{
+ return 1;
+}
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
new file mode 100644
index 0000000..486db8e
--- /dev/null
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -0,0 +1,47 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackArchiveGenerator_h
+#define cmCPackArchiveGenerator_h
+
+#include "cmCPackGenerator.h"
+
+
+/** \class cmCPackArchiveGenerator
+ * \brief A generator base for libarchive generation
+ *
+ */
+class cmCPackArchiveGenerator : public cmCPackGenerator
+{
+public:
+ enum CompressType{ GZIP, BZIP2, COMPRESS, LZMA, NONE};
+ enum ArchiveType{ TAR, ZIP};
+ cmTypeMacro(cmCPackArchiveGenerator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackArchiveGenerator(CompressType, ArchiveType);
+ virtual ~cmCPackArchiveGenerator();
+ // Used to add a header to the archive
+ virtual int GenerateHeader(std::ostream* os);
+
+protected:
+ virtual int InitializeInternal();
+ int CompressFiles(const char* outFileName, const char* toplevel,
+ const std::vector<std::string>& files);
+ virtual const char* GetOutputExtension() = 0;
+ CompressType Compress;
+ ArchiveType Archive;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx
index 99574b0..c6ef8ae 100644
--- a/Source/CPack/cmCPackTGZGenerator.cxx
+++ b/Source/CPack/cmCPackTGZGenerator.cxx
@@ -12,34 +12,11 @@
#include "cmCPackTGZGenerator.h"
-#include "cmake.h"
-#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
-#include "cmSystemTools.h"
-#include "cmMakefile.h"
-#include "cmGeneratedFileStream.h"
-#include "cmCPackLog.h"
-
-#include <cmsys/SystemTools.hxx>
-#include <cm_zlib.h>
-#include <libtar/libtar.h>
-#include <fcntl.h>
-#include <errno.h>
-
-//----------------------------------------------------------------------
-class cmCPackTGZGeneratorForward
-{
- public:
- static int GenerateHeader(cmCPackTGZGenerator* gg, std::ostream* os)
- {
- return gg->GenerateHeader(os);
- }
-};
-
//----------------------------------------------------------------------
cmCPackTGZGenerator::cmCPackTGZGenerator()
+ :cmCPackArchiveGenerator(cmCPackArchiveGenerator::GZIP,
+ cmCPackArchiveGenerator::TAR)
{
- this->Compress = true;
}
//----------------------------------------------------------------------
@@ -47,248 +24,3 @@ cmCPackTGZGenerator::~cmCPackTGZGenerator()
{
}
-static const size_t cmCPackTGZ_Data_BlockSize = 16384;
-
-//----------------------------------------------------------------------
-class cmCPackTGZ_Data
-{
-public:
- cmCPackTGZ_Data(cmCPackTGZGenerator* gen, bool compress) :
- OutputStream(0), Generator(gen),
- CompressionLevel(Z_DEFAULT_COMPRESSION),
- Compress(compress) {}
- std::ostream* OutputStream;
- cmCPackTGZGenerator* Generator;
- char CompressedBuffer[cmCPackTGZ_Data_BlockSize];
- int CompressionLevel;
- z_stream ZLibStream;
- uLong CRC;
- bool Compress;
-};
-
-//----------------------------------------------------------------------
-extern "C" {
- int cmCPackTGZ_Data_Open(void *client_data, const char* name, int oflags,
- mode_t mode);
- ssize_t cmCPackTGZ_Data_Write(void *client_data, void *buff, size_t n);
- int cmCPackTGZ_Data_Close(void *client_data);
-}
-
-
-//----------------------------------------------------------------------
-int cmCPackTGZ_Data_Open(void *client_data, const char* pathname,
- int, mode_t)
-{
- cmCPackTGZ_Data *mydata = (cmCPackTGZ_Data*)client_data;
-
- if ( mydata->Compress )
- {
- mydata->ZLibStream.zalloc = Z_NULL;
- mydata->ZLibStream.zfree = Z_NULL;
- mydata->ZLibStream.opaque = Z_NULL;
- int strategy = Z_DEFAULT_STRATEGY;
- if ( deflateInit2(&mydata->ZLibStream, mydata->CompressionLevel,
- Z_DEFLATED, -MAX_WBITS, 8, strategy) != Z_OK )
- {
- return -1;
- }
- }
-
- cmGeneratedFileStream* gf = new cmGeneratedFileStream;
- // Open binary
- gf->Open(pathname, false, true);
- mydata->OutputStream = gf;
- if ( !*mydata->OutputStream )
- {
- return -1;
- }
-
- if ( !cmCPackTGZGeneratorForward::GenerateHeader(mydata->Generator,gf))
- {
- return -1;
- }
-
- if ( mydata->Compress )
- {
- mydata->CRC = crc32(0L, Z_NULL, 0);
- }
-
- return 0;
-}
-
-//----------------------------------------------------------------------
-ssize_t cmCPackTGZ_Data_Write(void *client_data, void *buff, size_t n)
-{
- cmCPackTGZ_Data *mydata = (cmCPackTGZ_Data*)client_data;
-
- if ( mydata->Compress )
- {
- mydata->ZLibStream.avail_in = static_cast<uInt>(n);
- mydata->ZLibStream.next_in = reinterpret_cast<Bytef*>(buff);
-
- do {
- mydata->ZLibStream.avail_out = cmCPackTGZ_Data_BlockSize;
- mydata->ZLibStream.next_out
- = reinterpret_cast<Bytef*>(mydata->CompressedBuffer);
- // no bad return value
- int ret = deflate(&mydata->ZLibStream, (n?Z_NO_FLUSH:Z_FINISH));
- if(ret == Z_STREAM_ERROR)
- {
- return 0;
- }
-
- size_t compressedSize
- = cmCPackTGZ_Data_BlockSize - mydata->ZLibStream.avail_out;
-
- mydata->OutputStream->write(
- reinterpret_cast<const char*>(mydata->CompressedBuffer),
- compressedSize);
- } while ( mydata->ZLibStream.avail_out == 0 );
-
- if ( !*mydata->OutputStream )
- {
- return 0;
- }
- if ( n )
- {
- mydata->CRC = crc32(mydata->CRC, reinterpret_cast<Bytef *>(buff),
- static_cast<uInt>(n));
- }
- }
- else
- {
- mydata->OutputStream->write(reinterpret_cast<char*>(buff), n);
- }
- return n;
-}
-
-//----------------------------------------------------------------------
-int cmCPackTGZ_Data_Close(void *client_data)
-{
- cmCPackTGZ_Data *mydata = (cmCPackTGZ_Data*)client_data;
-
- if ( mydata->Compress )
- {
- cmCPackTGZ_Data_Write(client_data, 0, 0);
-
- char buffer[8];
- int n;
- uLong x = mydata->CRC;
- for (n = 0; n < 4; n++) {
- buffer[n] = static_cast<char>(x & 0xff);
- x >>= 8;
- }
- x = mydata->ZLibStream.total_in;
- for (n = 0; n < 4; n++) {
- buffer[n+4] = static_cast<char>(x & 0xff);
- x >>= 8;
- }
-
- mydata->OutputStream->write(buffer, 8);
- (void)deflateEnd(&mydata->ZLibStream);
- }
- delete mydata->OutputStream;
- mydata->OutputStream = 0;
- return (0);
-}
-
-//----------------------------------------------------------------------
-int cmCPackTGZGenerator::InitializeInternal()
-{
- this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
- return this->Superclass::InitializeInternal();
-}
-
-//----------------------------------------------------------------------
-int cmCPackTGZGenerator::CompressFiles(const char* outFileName,
- const char* toplevel, const std::vector<std::string>& files)
-{
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
- << (toplevel ? toplevel : "(NULL)") << std::endl);
- cmCPackTGZ_Data mydata(this, this->Compress);
- TAR *t;
- char buf[TAR_MAXPATHLEN];
- char pathname[TAR_MAXPATHLEN];
-
- tartype_t gztype = {
- (openfunc_t)cmCPackTGZ_Data_Open,
- (closefunc_t)cmCPackTGZ_Data_Close,
- (readfunc_t)0,
- (writefunc_t)cmCPackTGZ_Data_Write,
- &mydata
- };
-
- // This libtar is not const safe. Make a non-const copy of outFileName
- char* realName = new char[ strlen(outFileName) + 1 ];
- strcpy(realName, outFileName);
- int flags = O_WRONLY | O_CREAT;
- int options = 0;
- if(this->GeneratorVerbose)
- {
- options |= TAR_VERBOSE;
- }
-#ifdef __CYGWIN__
- options |= TAR_GNU;
-#endif
- if (tar_open(&t, realName,
- &gztype,
- flags, 0644,
- options) == -1)
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_open(): "
- << strerror(errno) << std::endl);
- delete [] realName;
- return 0;
- }
-
- delete [] realName;
-
- std::vector<std::string>::const_iterator fileIt;
- for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
- {
- std::string rp = cmSystemTools::RelativePath(toplevel, fileIt->c_str());
- strncpy(pathname, fileIt->c_str(), sizeof(pathname));
- pathname[sizeof(pathname)-1] = 0;
- strncpy(buf, rp.c_str(), sizeof(buf));
- buf[sizeof(buf)-1] = 0;
- if (tar_append_tree(t, pathname, buf) != 0)
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem with tar_append_tree(\"" << buf << "\", \""
- << pathname << "\"): "
- << strerror(errno) << std::endl);
- tar_close(t);
- return 0;
- }
- }
- if (tar_append_eof(t) != 0)
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_append_eof(): "
- << strerror(errno) << std::endl);
- tar_close(t);
- return 0;
- }
-
- if (tar_close(t) != 0)
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_close(): "
- << strerror(errno) << std::endl);
- return 0;
- }
- return 1;
-}
-
-//----------------------------------------------------------------------
-int cmCPackTGZGenerator::GenerateHeader(std::ostream* os)
-{
- if ( this->Compress )
- {
- const int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
- char header[11];
- sprintf(header, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/,
- 3 /* zlib os code for UNIX, not really used anyway */);
- os->write(header, 10);
- }
- return 1;
-}
diff --git a/Source/CPack/cmCPackTGZGenerator.h b/Source/CPack/cmCPackTGZGenerator.h
index 099775d..3a9fc6b 100644
--- a/Source/CPack/cmCPackTGZGenerator.h
+++ b/Source/CPack/cmCPackTGZGenerator.h
@@ -13,35 +13,23 @@
#ifndef cmCPackTGZGenerator_h
#define cmCPackTGZGenerator_h
-#include "cmCPackGenerator.h"
-
-class cmCPackTGZGeneratorForward;
+#include "cmCPackArchiveGenerator.h"
/** \class cmCPackTGZGenerator
* \brief A generator for TGZ files
*
- * http://people.freebsd.org/~kientzle/libarchive/
*/
-class cmCPackTGZGenerator : public cmCPackGenerator
+class cmCPackTGZGenerator : public cmCPackArchiveGenerator
{
public:
- friend class cmCPackTGZGeneratorForward;
- cmCPackTypeMacro(cmCPackTGZGenerator, cmCPackGenerator);
-
+ cmCPackTypeMacro(cmCPackTGZGenerator, cmCPackArchiveGenerator);
/**
* Construct generator
*/
cmCPackTGZGenerator();
virtual ~cmCPackTGZGenerator();
-
protected:
- virtual int InitializeInternal();
- virtual int GenerateHeader(std::ostream* os);
- int CompressFiles(const char* outFileName, const char* toplevel,
- const std::vector<std::string>& files);
virtual const char* GetOutputExtension() { return ".tar.gz"; }
-
- bool Compress;
};
#endif
diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx
index de7f16c..52826dc 100644
--- a/Source/CPack/cmCPackTarBZip2Generator.cxx
+++ b/Source/CPack/cmCPackTarBZip2Generator.cxx
@@ -11,29 +11,11 @@
============================================================================*/
#include "cmCPackTarBZip2Generator.h"
-
-#include "cmake.h"
-#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
-#include "cmSystemTools.h"
-#include "cmMakefile.h"
-#include "cmGeneratedFileStream.h"
-#include "cmCPackLog.h"
-
-#include <cmsys/SystemTools.hxx>
-
-// Includes needed for implementation of RenameFile. This is not in
-// system tools because it is not implemented robustly enough to move
-// files across directories.
-#ifdef _WIN32
-# include <windows.h>
-# include <sys/stat.h>
-#endif
-
//----------------------------------------------------------------------
-cmCPackTarBZip2Generator::cmCPackTarBZip2Generator()
+cmCPackTarBZip2Generator::cmCPackTarBZip2Generator()
+ :cmCPackArchiveGenerator(cmCPackArchiveGenerator::BZIP2,
+ cmCPackArchiveGenerator::TAR)
{
- this->Compress = false;
}
//----------------------------------------------------------------------
@@ -41,135 +23,3 @@ cmCPackTarBZip2Generator::~cmCPackTarBZip2Generator()
{
}
-//----------------------------------------------------------------------
-int cmCPackTarBZip2Generator::InitializeInternal()
-{
- this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
- std::vector<std::string> path;
- std::string pkgPath = cmSystemTools::FindProgram("bzip2", path, false);
- if ( pkgPath.empty() )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find BZip2" << std::endl);
- return 0;
- }
- this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath.c_str());
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Found Compress program: "
- << pkgPath.c_str()
- << std::endl);
-
- return this->Superclass::InitializeInternal();
-}
-
-//----------------------------------------------------------------------
-int cmCPackTarBZip2Generator::BZip2File(const char* packageDirFileName)
-{
- int retVal = 0;
- cmOStringStream dmgCmd1;
- dmgCmd1 << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
- << "\" \"" << packageDirFileName
- << "\"";
- retVal = -1;
- std::string output;
- int res = cmSystemTools::RunSingleCommand(dmgCmd1.str().c_str(), &output,
- &retVal, 0, this->GeneratorVerbose, 0);
- if ( !res || retVal )
- {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/CompressBZip2.log";
- cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << dmgCmd1.str().c_str() << std::endl
- << "# Output:" << std::endl
- << output.c_str() << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running BZip2 command: "
- << dmgCmd1.str().c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
- return 0;
- }
- return 1;
-}
-
-//----------------------------------------------------------------------
-int cmCPackTarBZip2Generator::CompressFiles(const char* outFileName,
- const char* toplevel, const std::vector<std::string>& files)
-{
- std::string packageDirFileName
- = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- packageDirFileName += ".tar";
- std::string output;
- if ( !this->Superclass::CompressFiles(packageDirFileName.c_str(),
- toplevel, files) )
- {
- return 0;
- }
-
- if(!this->BZip2File(packageDirFileName.c_str()))
- {
- return 0;
- }
-
- std::string compressOutFile = packageDirFileName + ".bz2";
- if ( !cmSystemTools::SameFile(compressOutFile.c_str(), outFileName ) )
- {
- if ( !this->RenameFile(compressOutFile.c_str(), outFileName) )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem renaming: \""
- << compressOutFile.c_str() << "\" to \""
- << (outFileName ? outFileName : "(NULL)") << std::endl);
- return 0;
- }
- }
-
- return 1;
-}
-
-//----------------------------------------------------------------------------
-int cmCPackTarBZip2Generator::RenameFile(const char* oldname,
- const char* newname)
-{
-#ifdef _WIN32
- /* On Windows the move functions will not replace existing files.
- Check if the destination exists. */
- struct stat newFile;
- if(stat(newname, &newFile) == 0)
- {
- /* The destination exists. We have to replace it carefully. The
- MoveFileEx function does what we need but is not available on
- Win9x. */
- OSVERSIONINFO osv;
- DWORD attrs;
-
- /* Make sure the destination is not read only. */
- attrs = GetFileAttributes(newname);
- if(attrs & FILE_ATTRIBUTE_READONLY)
- {
- SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
- }
-
- /* Check the windows version number. */
- osv.dwOSVersionInfoSize = sizeof(osv);
- GetVersionEx(&osv);
- if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
- {
- /* This is Win9x. There is no MoveFileEx implementation. We
- cannot quite rename the file atomically. Just delete the
- destination and then move the file. */
- DeleteFile(newname);
- return MoveFile(oldname, newname);
- }
- else
- {
- /* This is not Win9x. Use the MoveFileEx implementation. */
- return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING);
- }
- }
- else
- {
- /* The destination does not exist. Just move the file. */
- return MoveFile(oldname, newname);
- }
-#else
- /* On UNIX we have an OS-provided call to do this atomically. */
- return rename(oldname, newname) == 0;
-#endif
-}
-
diff --git a/Source/CPack/cmCPackTarBZip2Generator.h b/Source/CPack/cmCPackTarBZip2Generator.h
index 7b4ed65..74c244e 100644
--- a/Source/CPack/cmCPackTarBZip2Generator.h
+++ b/Source/CPack/cmCPackTarBZip2Generator.h
@@ -13,30 +13,22 @@
#ifndef cmCPackTarBZip2Generator_h
#define cmCPackTarBZip2Generator_h
-#include "cmCPackTGZGenerator.h"
+#include "cmCPackArchiveGenerator.h"
/** \class cmCPackTarBZip2Generator
* \brief A generator for TarBZip2 files
*/
-class cmCPackTarBZip2Generator : public cmCPackTGZGenerator
+class cmCPackTarBZip2Generator : public cmCPackArchiveGenerator
{
public:
- friend class cmCPackTarBZip2GeneratorForward;
- cmCPackTypeMacro(cmCPackTarBZip2Generator, cmCPackTGZGenerator);
-
+ cmCPackTypeMacro(cmCPackTarBZip2Generator, cmCPackArchiveGenerator);
/**
* Construct generator
*/
cmCPackTarBZip2Generator();
virtual ~cmCPackTarBZip2Generator();
-
protected:
- virtual int InitializeInternal();
- int CompressFiles(const char* outFileName, const char* toplevel,
- const std::vector<std::string>& files);
virtual const char* GetOutputExtension() { return ".tar.bz2"; }
- int BZip2File(const char* filename);
- int RenameFile(const char* oldname, const char* newname);
};
#endif
diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx
index 165c181..e9b5e2e 100644
--- a/Source/CPack/cmCPackTarCompressGenerator.cxx
+++ b/Source/CPack/cmCPackTarCompressGenerator.cxx
@@ -12,32 +12,10 @@
#include "cmCPackTarCompressGenerator.h"
-#include "cmake.h"
-#include "cmGlobalGenerator.h"
-#include "cmLocalGenerator.h"
-#include "cmSystemTools.h"
-#include "cmMakefile.h"
-#include "cmGeneratedFileStream.h"
-#include "cmCPackLog.h"
-
-#include <cmsys/SystemTools.hxx>
-#include <cmcompress/cmcompress.h>
-#include <libtar/libtar.h>
-#include <fcntl.h>
-#include <errno.h>
-
//----------------------------------------------------------------------
-class cmCPackTarCompressGeneratorForward
-{
-public:
- static int GenerateHeader(cmCPackTarCompressGenerator* gg, std::ostream* os)
- {
- return gg->GenerateHeader(os);
- }
-};
-
-//----------------------------------------------------------------------
-cmCPackTarCompressGenerator::cmCPackTarCompressGenerator()
+cmCPackTarCompressGenerator::cmCPackTarCompressGenerator()
+ :cmCPackArchiveGenerator(cmCPackArchiveGenerator::COMPRESS,
+ cmCPackArchiveGenerator::TAR)
{
}
@@ -46,206 +24,3 @@ cmCPackTarCompressGenerator::~cmCPackTarCompressGenerator()
{
}
-//----------------------------------------------------------------------
-class cmCPackTarCompress_Data
-{
-public:
- cmCPackTarCompress_Data(cmCPackTarCompressGenerator* gen) :
- OutputStream(0), Generator(gen) {}
- std::ostream* OutputStream;
- cmCPackTarCompressGenerator* Generator;
- cmcompress_stream CMCompressStream;
-};
-
-//----------------------------------------------------------------------
-extern "C" {
- // For cmTar
- int cmCPackTarCompress_Data_Open(void *client_data, const char* name,
- int oflags, mode_t mode);
- ssize_t cmCPackTarCompress_Data_Write(void *client_data, void *buff,
- size_t n);
- int cmCPackTarCompress_Data_Close(void *client_data);
-
- // For cmCompress
- int cmCPackTarCompress_Compress_Output(void* cdata, const char* data,
- int len);
-}
-
-
-//----------------------------------------------------------------------
-int cmCPackTarCompress_Data_Open(void *client_data, const char* pathname,
- int, mode_t)
-{
- cmCPackTarCompress_Data *mydata = (cmCPackTarCompress_Data*)client_data;
-
- if ( !cmcompress_compress_initialize(&mydata->CMCompressStream) )
- {
- return -1;
- }
-
- mydata->CMCompressStream.client_data = mydata;
- mydata->CMCompressStream.output_stream = cmCPackTarCompress_Compress_Output;
-
- cmGeneratedFileStream* gf = new cmGeneratedFileStream;
- // Open binary
- gf->Open(pathname, false, true);
- mydata->OutputStream = gf;
- if ( !*mydata->OutputStream )
- {
- return -1;
- }
-
- if ( !cmcompress_compress_start(&mydata->CMCompressStream) )
- {
- return -1;
- }
-
-
- if ( !cmCPackTarCompressGeneratorForward::GenerateHeader(
- mydata->Generator,gf))
- {
- return -1;
- }
-
- return 0;
-}
-
-//----------------------------------------------------------------------
-ssize_t cmCPackTarCompress_Data_Write(void *client_data, void *buff, size_t n)
-{
- cmCPackTarCompress_Data *mydata = (cmCPackTarCompress_Data*)client_data;
-
- if ( !cmcompress_compress(&mydata->CMCompressStream, buff, n) )
- {
- return 0;
- }
- return n;
-}
-
-//----------------------------------------------------------------------
-int cmCPackTarCompress_Data_Close(void *client_data)
-{
- cmCPackTarCompress_Data *mydata = (cmCPackTarCompress_Data*)client_data;
-
- if ( !cmcompress_compress_finalize(&mydata->CMCompressStream) )
- {
- delete mydata->OutputStream;
- return -1;
- }
-
- delete mydata->OutputStream;
- mydata->OutputStream = 0;
- return (0);
-}
-
-//----------------------------------------------------------------------
-int cmCPackTarCompressGenerator::InitializeInternal()
-{
- this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
- return this->Superclass::InitializeInternal();
-}
-
-//----------------------------------------------------------------------
-int cmCPackTarCompressGenerator::CompressFiles(const char* outFileName,
- const char* toplevel, const std::vector<std::string>& files)
-{
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
- << (toplevel ? toplevel : "(NULL)") << std::endl);
- cmCPackTarCompress_Data mydata(this);
- TAR *t;
- char buf[TAR_MAXPATHLEN];
- char pathname[TAR_MAXPATHLEN];
-
- tartype_t compressType = {
- (openfunc_t)cmCPackTarCompress_Data_Open,
- (closefunc_t)cmCPackTarCompress_Data_Close,
- (readfunc_t)0,
- (writefunc_t)cmCPackTarCompress_Data_Write,
- &mydata
- };
-
- // This libtar is not const safe. Make a non-const copy of outFileName
- char* realName = new char[ strlen(outFileName) + 1 ];
- strcpy(realName, outFileName);
- int flags = O_WRONLY | O_CREAT;
- int options = 0;
- if(this->GeneratorVerbose)
- {
- options |= TAR_VERBOSE;
- }
-#ifdef __CYGWIN__
- options |= TAR_GNU;
-#endif
- if (tar_open(&t, realName,
- &compressType,
- flags, 0644,
- options) == -1)
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_open(): "
- << strerror(errno) << std::endl);
- delete [] realName;
- return 0;
- }
-
- delete [] realName;
-
- std::vector<std::string>::const_iterator fileIt;
- for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
- {
- std::string rp = cmSystemTools::RelativePath(toplevel, fileIt->c_str());
- strncpy(pathname, fileIt->c_str(), sizeof(pathname));
- pathname[sizeof(pathname)-1] = 0;
- strncpy(buf, rp.c_str(), sizeof(buf));
- buf[sizeof(buf)-1] = 0;
- if (tar_append_tree(t, pathname, buf) != 0)
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem with tar_append_tree(\"" << buf << "\", \""
- << pathname << "\"): "
- << strerror(errno) << std::endl);
- tar_close(t);
- return 0;
- }
- }
- if (tar_append_eof(t) != 0)
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_append_eof(): "
- << strerror(errno) << std::endl);
- tar_close(t);
- return 0;
- }
-
- if (tar_close(t) != 0)
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_close(): "
- << strerror(errno) << std::endl);
- return 0;
- }
- return 1;
-}
-
-//----------------------------------------------------------------------
-int cmCPackTarCompress_Compress_Output(void* client_data,
- const char* data, int data_length)
-{
- if(!client_data)
- {
- return 0;
- }
- cmcompress_stream *cstream = static_cast<cmcompress_stream*>(client_data);
- cmCPackTarCompress_Data *mydata
- = static_cast<cmCPackTarCompress_Data*>(cstream->client_data);
- if ( !mydata->OutputStream )
- {
- return 0;
- }
- mydata->OutputStream->write(data, data_length);
- return data_length;
-}
-
-//----------------------------------------------------------------------
-int cmCPackTarCompressGenerator::GenerateHeader(std::ostream* os)
-{
- (void)os;
- return 1;
-}
diff --git a/Source/CPack/cmCPackTarCompressGenerator.h b/Source/CPack/cmCPackTarCompressGenerator.h
index 3c18056..7ff9a0a 100644
--- a/Source/CPack/cmCPackTarCompressGenerator.h
+++ b/Source/CPack/cmCPackTarCompressGenerator.h
@@ -18,12 +18,10 @@
/** \class cmCPackTarCompressGenerator
* \brief A generator for TarCompress files
*/
-class cmCPackTarCompressGenerator : public cmCPackTGZGenerator
+class cmCPackTarCompressGenerator : public cmCPackArchiveGenerator
{
public:
- friend class cmCPackTarCompressGeneratorForward;
- cmCPackTypeMacro(cmCPackTarCompressGenerator, cmCPackTGZGenerator);
-
+ cmCPackTypeMacro(cmCPackTarCompressGenerator, cmCPackArchiveGenerator);
/**
* Construct generator
*/
@@ -31,13 +29,7 @@ public:
virtual ~cmCPackTarCompressGenerator();
protected:
- virtual int InitializeInternal();
- int CompressFiles(const char* outFileName, const char* toplevel,
- const std::vector<std::string>& files);
virtual const char* GetOutputExtension() { return ".tar.Z"; }
-
- int RenameFile(const char* oldname, const char* newname);
- int GenerateHeader(std::ostream* os);
};
#endif
diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx
index 9924497..e195f83 100644
--- a/Source/CPack/cmCPackZIPGenerator.cxx
+++ b/Source/CPack/cmCPackZIPGenerator.cxx
@@ -12,14 +12,10 @@
#include "cmCPackZIPGenerator.h"
-#include "cmSystemTools.h"
-#include "cmGeneratedFileStream.h"
-#include "cmCPackLog.h"
-
-#include <cmsys/SystemTools.hxx>
-
//----------------------------------------------------------------------
cmCPackZIPGenerator::cmCPackZIPGenerator()
+ :cmCPackArchiveGenerator(cmCPackArchiveGenerator::NONE,
+ cmCPackArchiveGenerator::ZIP)
{
}
@@ -28,71 +24,3 @@ cmCPackZIPGenerator::~cmCPackZIPGenerator()
{
}
-//----------------------------------------------------------------------
-int cmCPackZIPGenerator::InitializeInternal()
-{
- this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
- this->ReadListFile("CPackZIP.cmake");
- if ((!this->IsSet("ZIP_EXECUTABLE"))
- || (!this->IsSet("CPACK_ZIP_COMMAND")))
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find a suitable ZIP program"
- << std::endl);
- return 0;
- }
- return this->Superclass::InitializeInternal();
-}
-
-//----------------------------------------------------------------------
-int cmCPackZIPGenerator::CompressFiles(const char* outFileName,
- const char* toplevel, const std::vector<std::string>& files)
-{
- std::string tempFileName;
- tempFileName = toplevel;
- tempFileName += "/winZip.filelist";
- bool needQuotesInFile = cmSystemTools::IsOn(
- this->GetOption("CPACK_ZIP_NEED_QUOTES"));
-
- std::string cmd = this->GetOption("CPACK_ZIP_COMMAND");
- cmsys::SystemTools::ReplaceString(cmd, "<ARCHIVE>", outFileName);
- cmsys::SystemTools::ReplaceString(cmd, "<FILELIST>", "winZip.filelist");
-
- { // the scope is needed for cmGeneratedFileStream
- cmGeneratedFileStream out(tempFileName.c_str());
- std::vector<std::string>::const_iterator fileIt;
- for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
- {
- if ( needQuotesInFile )
- {
- out << "\"";
- }
- out << cmSystemTools::RelativePath(toplevel, fileIt->c_str());
- if ( needQuotesInFile )
- {
- out << "\"";
- }
- out << std::endl;
- }
- }
-
-
- std::string output;
- int retVal = -1;
- int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output,
- &retVal, toplevel, this->GeneratorVerbose, 0);
-
- if ( !res || retVal )
- {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/CompressZip.log";
- cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << cmd.c_str() << std::endl
- << "# Output:" << std::endl
- << output.c_str() << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running zip command: "
- << cmd.c_str() << std::endl
- << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
- return 0;
- }
- return 1;
-}
diff --git a/Source/CPack/cmCPackZIPGenerator.h b/Source/CPack/cmCPackZIPGenerator.h
index 7ff0dc3..70e1a5f 100644
--- a/Source/CPack/cmCPackZIPGenerator.h
+++ b/Source/CPack/cmCPackZIPGenerator.h
@@ -13,18 +13,15 @@
#ifndef cmCPackZIPGenerator_h
#define cmCPackZIPGenerator_h
-#include "cmCPackGenerator.h"
-
-class cmCPackZIPGeneratorForward;
+#include "cmCPackArchiveGenerator.h"
/** \class cmCPackZIPGenerator
* \brief A generator for ZIP files
*/
-class cmCPackZIPGenerator : public cmCPackGenerator
+class cmCPackZIPGenerator : public cmCPackArchiveGenerator
{
public:
- friend class cmCPackZIPGeneratorForward;
- cmCPackTypeMacro(cmCPackZIPGenerator, cmCPackGenerator);
+ cmCPackTypeMacro(cmCPackZIPGenerator, cmCPackArchiveGenerator);
/**
* Construct generator
@@ -33,12 +30,7 @@ public:
virtual ~cmCPackZIPGenerator();
protected:
- virtual int InitializeInternal();
- int CompressFiles(const char* outFileName, const char* toplevel,
- const std::vector<std::string>& files);
virtual const char* GetOutputExtension() { return ".zip"; }
-
- int ZipStyle;
};
#endif
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 031bfc3..d593d7e 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -18,11 +18,13 @@
#ifdef __QNX__
# include <malloc.h> /* for malloc/free on QNX */
#endif
-
+#include <cmsys/Glob.hxx>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/Directory.hxx>
#include <cmsys/System.h>
#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include <cmlibarchive/libarchive/archive.h>
+#include <cmlibarchive/libarchive/archive_entry.h>
# include <cmsys/Terminal.h>
#endif
#include <cmsys/stl/algorithm>
@@ -45,9 +47,8 @@
#endif
#if defined(CMAKE_BUILD_WITH_CMAKE)
-# include <libtar/libtar.h>
+# include <memory> // auto_ptr
# include <fcntl.h>
-# include <cm_zlib.h>
# include <cmsys/MD5.h>
#endif
@@ -1701,166 +1702,111 @@ bool cmSystemTools::IsPathToFramework(const char* path)
return false;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
-struct cmSystemToolsGZStruct
-{
- gzFile GZFile;
-};
-
-extern "C" {
- int cmSystemToolsGZStructOpen(void* call_data, const char *pathname,
- int oflags, mode_t mode);
- int cmSystemToolsGZStructClose(void* call_data);
- ssize_t cmSystemToolsGZStructRead(void* call_data, void* buf, size_t count);
- ssize_t cmSystemToolsGZStructWrite(void* call_data, const void* buf,
- size_t count);
-}
-
-int cmSystemToolsGZStructOpen(void* call_data, const char *pathname,
- int oflags, mode_t mode)
-{
- const char *gzoflags;
- int fd;
-
- cmSystemToolsGZStruct* gzf = static_cast<cmSystemToolsGZStruct*>(call_data);
-
- 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;
- }
-
-// no fchmod on BeOS 5...do pathname instead.
-#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__)
- if ((oflags & O_CREAT) && chmod(pathname, mode))
- {
- return -1;
- }
-#elif !defined(_WIN32) || defined(__CYGWIN__)
- if ((oflags & O_CREAT) && fchmod(fd, mode))
- {
- return -1;
- }
-#endif
-
- gzf->GZFile = gzdopen(fd, gzoflags);
- if (!gzf->GZFile)
- {
- errno = ENOMEM;
- return -1;
- }
-
- return fd;
-}
-
-int cmSystemToolsGZStructClose(void* call_data)
-{
- cmSystemToolsGZStruct* gzf = static_cast<cmSystemToolsGZStruct*>(call_data);
- return gzclose(gzf->GZFile);
-}
-
-ssize_t cmSystemToolsGZStructRead(void* call_data, void* buf, size_t count)
-{
- cmSystemToolsGZStruct* gzf = static_cast<cmSystemToolsGZStruct*>(call_data);
- return gzread(gzf->GZFile, buf, static_cast<int>(count));
-}
-
-ssize_t cmSystemToolsGZStructWrite(void* call_data, const void* buf,
- size_t count)
-{
- cmSystemToolsGZStruct* gzf = static_cast<cmSystemToolsGZStruct*>(call_data);
- return gzwrite(gzf->GZFile, (void*)buf, static_cast<int>(count));
-}
-
-#endif
-
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];
- cmSystemToolsGZStruct gzs;
-
- tartype_t gztype = {
- (openfunc_t)cmSystemToolsGZStructOpen,
- (closefunc_t)cmSystemToolsGZStructClose,
- (readfunc_t)cmSystemToolsGZStructRead,
- (writefunc_t)cmSystemToolsGZStructWrite,
- &gzs
- };
-
- // This libtar is not const safe. Make a non-const copy of outFileName
- char* realName = new char[ strlen(outFileName) + 1 ];
- strcpy(realName, outFileName);
- int options = 0;
- if(verbose)
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ // recursively expand all directories in files so that we have a list
+ // of files
+ std::vector<std::string> expandedFiles;
+ for(std::vector<cmStdString>::const_iterator i = files.begin();
+ i != files.end(); ++i)
{
- options |= TAR_VERBOSE;
- }
-#ifdef __CYGWIN__
- options |= TAR_GNU;
-#endif
- if (tar_open(&t, realName,
- (gzip? &gztype : NULL),
- O_WRONLY | O_CREAT, 0644,
- options) == -1)
- {
- cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
- delete [] realName;
- return false;
+ if(cmSystemTools::FileIsDirectory(i->c_str()))
+ {
+ cmsys::Glob gl;
+ std::string findExpr = *i;
+ if ( findExpr[findExpr.size()-1] != '/' )
+ {
+ findExpr +="/";
+ }
+ findExpr += "*";
+ gl.RecurseOn();
+ if ( gl.FindFiles(findExpr) )
+ {
+ std::vector<std::string> dirfiles = gl.GetFiles();
+ std::copy(dirfiles.begin(), dirfiles.end(),
+ std::back_inserter(expandedFiles));
+ }
+ }
+ else
+ {
+ if(!cmSystemTools::FileIsFullPath(i->c_str()))
+ {
+ std::string fullp = cwd + "/" + *i;
+ expandedFiles.push_back(fullp);
+ }
+ else
+ {
+ expandedFiles.push_back(*i);
+ }
+ }
}
-
- delete [] realName;
-
- std::vector<cmStdString>::const_iterator it;
- for (it = files.begin(); it != files.end(); ++ it )
+ int res;
+ // create a new archive
+ struct archive* a = archive_write_new();
+ if(gzip)
{
- strncpy(pathname, it->c_str(), sizeof(pathname));
- pathname[sizeof(pathname)-1] = 0;
- strncpy(buf, pathname, sizeof(buf));
- buf[sizeof(buf)-1] = 0;
- if (tar_append_tree(t, buf, pathname) != 0)
+ res = archive_write_set_compression_gzip(a);
+ if(res != ARCHIVE_OK)
{
- cmOStringStream ostr;
- ostr << "Problem with tar_append_tree(\"" << buf << "\", \""
- << pathname << "\"): "
- << strerror(errno);
- cmSystemTools::Error(ostr.str().c_str());
- tar_close(t);
- return false;
+ cmSystemTools::Error("Unable to use gzip in libarchive");
}
- }
-
- if (tar_append_eof(t) != 0)
+ }
+ res = archive_write_set_format_ustar(a);
+ if(res != ARCHIVE_OK)
{
- cmSystemTools::Error("Problem with tar_append_eof(): ", strerror(errno));
- tar_close(t);
- return false;
+ cmSystemTools::Error("Unable to use tar libarchive");
}
-
- if (tar_close(t) != 0)
+ archive_write_open_file(a, outFileName);
+ // create a new disk struct
+ struct archive* disk = archive_read_disk_new();
+ archive_read_disk_set_standard_lookup(disk);
+ std::vector<std::string>::const_iterator fileIt;
+ for ( fileIt = expandedFiles.begin();
+ fileIt != expandedFiles.end(); ++ fileIt )
{
- cmSystemTools::Error("Problem with tar_close(): ", strerror(errno));
- return false;
+ // create a new entry for each file
+ struct archive_entry *entry = archive_entry_new();
+ // Get the relative path to the file
+ std::string rp = cmSystemTools::RelativePath(cwd.c_str(),
+ fileIt->c_str());
+ if(verbose)
+ {
+ std::cout << rp << "\n";
+ }
+ // Set the name of the entry to the file name
+ archive_entry_set_pathname(entry, rp.c_str());
+ // get the information about the file from stat
+ struct stat s;
+ stat(fileIt->c_str(), &s);
+ archive_read_disk_entry_from_file(disk, entry, -1, &s);
+ // write entry header
+ archive_write_header(a, entry);
+ // now copy contents of file into archive a
+ FILE* file = fopen(fileIt->c_str(), "rb");
+ if(!file)
+ {
+ cmSystemTools::Error("Problem with fopen(): ",
+ fileIt->c_str());
+ return false;
+ }
+ char buff[16384];
+ int len = fread(buff, 1, sizeof(buff), file);
+ while (len > 0)
+ {
+ archive_write_data(a, buff, len);
+ len = fread(buff, 1, sizeof(buff), file);
+ }
+ // close the file and free the entry
+ fclose(file);
+ archive_entry_free(entry);
}
-
+ // close the archive and finish the write
+ archive_write_close(a);
+ archive_write_finish(a);
return true;
#else
(void)outFileName;
@@ -1871,130 +1817,245 @@ bool cmSystemTools::CreateTar(const char* outFileName,
#endif
}
-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;
- cmSystemToolsGZStruct gzs;
-
- tartype_t gztype = {
- cmSystemToolsGZStructOpen,
- cmSystemToolsGZStructClose,
- cmSystemToolsGZStructRead,
- cmSystemToolsGZStructWrite,
- &gzs
- };
-
- // This libtar is not const safe. Make a non-const copy of outFileName
- char* realName = new char[ strlen(outFileName) + 1 ];
- 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)
+namespace{
+#define BSDTAR_FILESIZE_PRINTF "%lu"
+#define BSDTAR_FILESIZE_TYPE unsigned long
+ void
+list_item_verbose(FILE *out, struct archive_entry *entry)
+{
+ char tmp[100];
+ size_t w;
+ const char *p;
+ const char *fmt;
+ time_t tim;
+ static time_t now;
+ size_t u_width = 6;
+ size_t gs_width = 13;
+
+ /*
+ * We avoid collecting the entire list in memory at once by
+ * listing things as we see them. However, that also means we can't
+ * just pre-compute the field widths. Instead, we start with guesses
+ * and just widen them as necessary. These numbers are completely
+ * arbitrary.
+ */
+ if (!now)
+ {
+ time(&now);
+ }
+ fprintf(out, "%s %d ",
+ archive_entry_strmode(entry),
+ archive_entry_nlink(entry));
+
+ /* Use uname if it's present, else uid. */
+ p = archive_entry_uname(entry);
+ if ((p == NULL) || (*p == '\0'))
{
- cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
- delete [] realName;
- return false;
+ sprintf(tmp, "%lu ",
+ (unsigned long)archive_entry_uid(entry));
+ p = tmp;
}
-
- delete [] realName;
-
- if (tar_extract_all(t, 0) != 0)
- {
- cmSystemTools::Error("Problem with tar_extract_all(): ", strerror(errno));
- return false;
- }
-
- if (tar_close(t) != 0)
+ w = strlen(p);
+ if (w > u_width)
{
- cmSystemTools::Error("Problem with tar_close(): ", strerror(errno));
- return false;
+ u_width = w;
}
- return true;
+ fprintf(out, "%-*s ", (int)u_width, p);
+
+ /* Use gname if it's present, else gid. */
+ p = archive_entry_gname(entry);
+ if (p != NULL && p[0] != '\0')
+ {
+ fprintf(out, "%s", p);
+ w = strlen(p);
+ }
+ else
+ {
+ sprintf(tmp, "%lu",
+ (unsigned long)archive_entry_gid(entry));
+ w = strlen(tmp);
+ fprintf(out, "%s", tmp);
+ }
+
+ /*
+ * Print device number or file size, right-aligned so as to make
+ * total width of group and devnum/filesize fields be gs_width.
+ * If gs_width is too small, grow it.
+ */
+ if (archive_entry_filetype(entry) == AE_IFCHR
+ || archive_entry_filetype(entry) == AE_IFBLK)
+ {
+ sprintf(tmp, "%lu,%lu",
+ (unsigned long)archive_entry_rdevmajor(entry),
+ (unsigned long)archive_entry_rdevminor(entry));
+ }
+ else
+ {
+ /*
+ * Note the use of platform-dependent macros to format
+ * the filesize here. We need the format string and the
+ * corresponding type for the cast.
+ */
+ sprintf(tmp, BSDTAR_FILESIZE_PRINTF,
+ (BSDTAR_FILESIZE_TYPE)archive_entry_size(entry));
+ }
+ if (w + strlen(tmp) >= gs_width)
+ {
+ gs_width = w+strlen(tmp)+1;
+ }
+ fprintf(out, "%*s", (int)(gs_width - w), tmp);
+
+ /* Format the time using 'ls -l' conventions. */
+ tim = archive_entry_mtime(entry);
+#define HALF_YEAR (time_t)365 * 86400 / 2
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define DAY_FMT "%d" /* Windows' strftime function does not support %e format. */
#else
- (void)outFileName;
- (void)gzip;
- (void)verbose;
- return false;
+#define DAY_FMT "%e" /* Day number without leading zeros */
#endif
+ if (tim < now - HALF_YEAR || tim > now + HALF_YEAR)
+ {
+ fmt = DAY_FMT " %b %Y";
+ }
+ else
+ {
+ fmt = DAY_FMT " %b %H:%M";
+ }
+ strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
+ fprintf(out, " %s ", tmp);
+ fprintf(out, "%s", archive_entry_pathname(entry));
+
+ /* Extra information for links. */
+ if (archive_entry_hardlink(entry)) /* Hard link */
+ {
+ fprintf(out, " link to %s",
+ archive_entry_hardlink(entry));
+ }
+ else if (archive_entry_symlink(entry)) /* Symbolic link */
+ {
+ fprintf(out, " -> %s", archive_entry_symlink(entry));
+ }
}
-
-bool cmSystemTools::ListTar(const char* outFileName,
- std::vector<cmStdString>& files, bool gzip,
- bool verbose)
+
+int copy_data(struct archive *ar, struct archive *aw)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
- TAR *t;
- cmSystemToolsGZStruct gzs;
-
- tartype_t gztype = {
- cmSystemToolsGZStructOpen,
- cmSystemToolsGZStructClose,
- cmSystemToolsGZStructRead,
- cmSystemToolsGZStructWrite,
- &gzs
- };
-
- // This libtar is not const safe. Make a non-const copy of outFileName
- char* realName = new char[ strlen(outFileName) + 1 ];
- 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)
+ int r;
+ const void *buff;
+ size_t size;
+ off_t offset;
+
+ for (;;)
{
- cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
- delete [] realName;
- return false;
+ r = archive_read_data_block(ar, &buff, &size, &offset);
+ if (r == ARCHIVE_EOF)
+ {
+ return (ARCHIVE_OK);
+ }
+ if (r != ARCHIVE_OK)
+ {
+ return (r);
+ }
+ r = archive_write_data_block(aw, buff, size, offset);
+ if (r != ARCHIVE_OK)
+ {
+ cmSystemTools::Message("archive_write_data_block()",
+ archive_error_string(aw));
+ return (r);
+ }
}
+}
- delete [] realName;
-
- while ((th_read(t)) == 0)
- {
- const char* filename = th_get_pathname(t);
- files.push_back(filename);
-
- if ( verbose )
+bool extract_tar(const char* outFileName, bool verbose, bool extract)
+{
+ struct archive* a = archive_read_new();
+ struct archive *ext = archive_write_disk_new();
+ archive_read_support_compression_all(a);
+ archive_read_support_format_all(a);
+ struct archive_entry *entry;
+ int r = archive_read_open_file(a, outFileName, 10240);
+ if(r)
+ {
+ cmSystemTools::Error("Problem with archive_read_open_file(): ",
+ archive_error_string(a));
+ return false;
+ }
+ for (;;)
+ {
+ r = archive_read_next_header(a, &entry);
+ if (r == ARCHIVE_EOF)
+ {
+ break;
+ }
+ if (r != ARCHIVE_OK)
+ {
+ cmSystemTools::Error("Problem with archive_read_next_header(): ",
+ archive_error_string(a));
+ }
+ if (verbose && extract)
+ {
+ cmSystemTools::Stdout("x ");
+ }
+ if(verbose && !extract)
{
- th_print_long_ls(t);
+ list_item_verbose(stdout, entry);
}
else
{
- std::cout << filename << std::endl;
+ cmSystemTools::Stdout(archive_entry_pathname(entry));
}
-
-#ifdef DEBUG
- th_print(t);
-#endif
- if (TH_ISREG(t) && tar_skip_regfile(t) != 0)
+ if(extract)
{
- cmSystemTools::Error("Problem with tar_skip_regfile(): ",
- strerror(errno));
- return false;
+ r = archive_write_header(ext, entry);
+ if (r != ARCHIVE_OK)
+ {
+ cmSystemTools::Error("Problem with archive_write_header(): ",
+ archive_error_string(a));
+ }
+ else
+ {
+ copy_data(a, ext);
+ r = archive_write_finish_entry(ext);
+ if (r != ARCHIVE_OK)
+ {
+ cmSystemTools::Error("Problem with archive_write_finish_entry(): ",
+ archive_error_string(ext));
+ }
+ }
+ }
+ if (verbose || !extract)
+ {
+ cmSystemTools::Stdout("\n");
}
- }
-
- if (tar_close(t) != 0)
- {
- cmSystemTools::Error("Problem with tar_close(): ", strerror(errno));
- return false;
}
+ archive_read_close(a);
+ archive_read_finish(a);
return true;
+
+}
+}
+#endif
+
+bool cmSystemTools::ExtractTar(const char* outFileName,
+ const std::vector<cmStdString>& files,
+ bool , bool verbose)
+{
+ (void)files;
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ return extract_tar(outFileName, verbose, true);
+#else
+ (void)outFileName;
+ (void)verbose;
+ return false;
+#endif
+}
+
+bool cmSystemTools::ListTar(const char* outFileName,
+ std::vector<cmStdString>& files, bool gzip,
+ bool verbose)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ return extract_tar(outFileName, verbose, false);
#else
(void)outFileName;
(void)files;