Resync.
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / CPack / cmCPackTarCompressGenerator.cxx
blob70e5a298fd4a0f140be1ee66077fce79e33e1e59
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmCPackTarCompressGenerator.cxx,v $
5 Language: C++
6 Date: $Date: 2007/07/31 02:51:21 $
7 Version: $Revision: 1.9 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
18 #include "cmCPackTarCompressGenerator.h"
20 #include "cmake.h"
21 #include "cmGlobalGenerator.h"
22 #include "cmLocalGenerator.h"
23 #include "cmSystemTools.h"
24 #include "cmMakefile.h"
25 #include "cmGeneratedFileStream.h"
26 #include "cmCPackLog.h"
28 #include <cmsys/SystemTools.hxx>
29 #include <cmcompress/cmcompress.h>
30 #include <libtar/libtar.h>
31 #include <memory> // auto_ptr
32 #include <fcntl.h>
33 #include <errno.h>
35 //----------------------------------------------------------------------
36 class cmCPackTarCompressGeneratorForward
38 public:
39 static int GenerateHeader(cmCPackTarCompressGenerator* gg, std::ostream* os)
41 return gg->GenerateHeader(os);
45 //----------------------------------------------------------------------
46 cmCPackTarCompressGenerator::cmCPackTarCompressGenerator()
50 //----------------------------------------------------------------------
51 cmCPackTarCompressGenerator::~cmCPackTarCompressGenerator()
55 //----------------------------------------------------------------------
56 class cmCPackTarCompress_Data
58 public:
59 cmCPackTarCompress_Data(cmCPackTarCompressGenerator* gen) :
60 OutputStream(0), Generator(gen) {}
61 std::ostream* OutputStream;
62 cmCPackTarCompressGenerator* Generator;
63 cmcompress_stream CMCompressStream;
66 //----------------------------------------------------------------------
67 extern "C" {
68 // For cmTar
69 int cmCPackTarCompress_Data_Open(void *client_data, const char* name,
70 int oflags, mode_t mode);
71 ssize_t cmCPackTarCompress_Data_Write(void *client_data, void *buff,
72 size_t n);
73 int cmCPackTarCompress_Data_Close(void *client_data);
75 // For cmCompress
76 int cmCPackTarCompress_Compress_Output(void* cdata, const char* data,
77 int len);
81 //----------------------------------------------------------------------
82 int cmCPackTarCompress_Data_Open(void *client_data, const char* pathname,
83 int, mode_t)
85 cmCPackTarCompress_Data *mydata = (cmCPackTarCompress_Data*)client_data;
87 if ( !cmcompress_compress_initialize(&mydata->CMCompressStream) )
89 return -1;
92 mydata->CMCompressStream.client_data = mydata;
93 mydata->CMCompressStream.output_stream = cmCPackTarCompress_Compress_Output;
95 cmGeneratedFileStream* gf = new cmGeneratedFileStream;
96 // Open binary
97 gf->Open(pathname, false, true);
98 mydata->OutputStream = gf;
99 if ( !*mydata->OutputStream )
101 return -1;
104 if ( !cmcompress_compress_start(&mydata->CMCompressStream) )
106 return -1;
110 if ( !cmCPackTarCompressGeneratorForward::GenerateHeader(
111 mydata->Generator,gf))
113 return -1;
116 return 0;
119 //----------------------------------------------------------------------
120 ssize_t cmCPackTarCompress_Data_Write(void *client_data, void *buff, size_t n)
122 cmCPackTarCompress_Data *mydata = (cmCPackTarCompress_Data*)client_data;
124 if ( !cmcompress_compress(&mydata->CMCompressStream, buff, n) )
126 return 0;
128 return n;
131 //----------------------------------------------------------------------
132 int cmCPackTarCompress_Data_Close(void *client_data)
134 cmCPackTarCompress_Data *mydata = (cmCPackTarCompress_Data*)client_data;
136 if ( !cmcompress_compress_finalize(&mydata->CMCompressStream) )
138 delete mydata->OutputStream;
139 return -1;
142 delete mydata->OutputStream;
143 mydata->OutputStream = 0;
144 return (0);
147 //----------------------------------------------------------------------
148 int cmCPackTarCompressGenerator::InitializeInternal()
150 this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
151 return this->Superclass::InitializeInternal();
154 //----------------------------------------------------------------------
155 int cmCPackTarCompressGenerator::CompressFiles(const char* outFileName,
156 const char* toplevel, const std::vector<std::string>& files)
158 cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
159 << (toplevel ? toplevel : "(NULL)") << std::endl);
160 cmCPackTarCompress_Data mydata(this);
161 TAR *t;
162 char buf[TAR_MAXPATHLEN];
163 char pathname[TAR_MAXPATHLEN];
165 tartype_t compressType = {
166 (openfunc_t)cmCPackTarCompress_Data_Open,
167 (closefunc_t)cmCPackTarCompress_Data_Close,
168 (readfunc_t)0,
169 (writefunc_t)cmCPackTarCompress_Data_Write,
170 &mydata
173 // Ok, this libtar is not const safe. for now use auto_ptr hack
174 char* realName = new char[ strlen(outFileName) + 1 ];
175 std::auto_ptr<char> realNamePtr(realName);
176 strcpy(realName, outFileName);
177 int flags = O_WRONLY | O_CREAT;
178 int options = 0;
179 if(this->GeneratorVerbose)
181 options |= TAR_VERBOSE;
183 #ifdef __CYGWIN__
184 options |= TAR_GNU;
185 #endif
186 if (tar_open(&t, realName,
187 &compressType,
188 flags, 0644,
189 options) == -1)
191 cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_open(): "
192 << strerror(errno) << std::endl);
193 return 0;
196 std::vector<std::string>::const_iterator fileIt;
197 for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
199 std::string rp = cmSystemTools::RelativePath(toplevel, fileIt->c_str());
200 strncpy(pathname, fileIt->c_str(), sizeof(pathname));
201 pathname[sizeof(pathname)-1] = 0;
202 strncpy(buf, rp.c_str(), sizeof(buf));
203 buf[sizeof(buf)-1] = 0;
204 if (tar_append_tree(t, pathname, buf) != 0)
206 cmCPackLogger(cmCPackLog::LOG_ERROR,
207 "Problem with tar_append_tree(\"" << buf << "\", \""
208 << pathname << "\"): "
209 << strerror(errno) << std::endl);
210 tar_close(t);
211 return 0;
214 if (tar_append_eof(t) != 0)
216 cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_append_eof(): "
217 << strerror(errno) << std::endl);
218 tar_close(t);
219 return 0;
222 if (tar_close(t) != 0)
224 cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_close(): "
225 << strerror(errno) << std::endl);
226 return 0;
228 return 1;
231 //----------------------------------------------------------------------
232 int cmCPackTarCompress_Compress_Output(void* client_data,
233 const char* data, int data_length)
235 if(!client_data)
237 return 0;
239 cmcompress_stream *cstream = static_cast<cmcompress_stream*>(client_data);
240 cmCPackTarCompress_Data *mydata
241 = static_cast<cmCPackTarCompress_Data*>(cstream->client_data);
242 if ( !mydata->OutputStream )
244 return 0;
246 mydata->OutputStream->write(data, data_length);
247 return data_length;
250 //----------------------------------------------------------------------
251 int cmCPackTarCompressGenerator::GenerateHeader(std::ostream* os)
253 (void)os;
254 return 1;