1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmCPackTarCompressGenerator.cxx,v $
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"
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
35 //----------------------------------------------------------------------
36 class cmCPackTarCompressGeneratorForward
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
59 cmCPackTarCompress_Data(cmCPackTarCompressGenerator
* gen
) :
60 OutputStream(0), Generator(gen
) {}
61 std::ostream
* OutputStream
;
62 cmCPackTarCompressGenerator
* Generator
;
63 cmcompress_stream CMCompressStream
;
66 //----------------------------------------------------------------------
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
,
73 int cmCPackTarCompress_Data_Close(void *client_data
);
76 int cmCPackTarCompress_Compress_Output(void* cdata
, const char* data
,
81 //----------------------------------------------------------------------
82 int cmCPackTarCompress_Data_Open(void *client_data
, const char* pathname
,
85 cmCPackTarCompress_Data
*mydata
= (cmCPackTarCompress_Data
*)client_data
;
87 if ( !cmcompress_compress_initialize(&mydata
->CMCompressStream
) )
92 mydata
->CMCompressStream
.client_data
= mydata
;
93 mydata
->CMCompressStream
.output_stream
= cmCPackTarCompress_Compress_Output
;
95 cmGeneratedFileStream
* gf
= new cmGeneratedFileStream
;
97 gf
->Open(pathname
, false, true);
98 mydata
->OutputStream
= gf
;
99 if ( !*mydata
->OutputStream
)
104 if ( !cmcompress_compress_start(&mydata
->CMCompressStream
) )
110 if ( !cmCPackTarCompressGeneratorForward::GenerateHeader(
111 mydata
->Generator
,gf
))
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
) )
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
;
142 delete mydata
->OutputStream
;
143 mydata
->OutputStream
= 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);
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
,
169 (writefunc_t
)cmCPackTarCompress_Data_Write
,
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
;
179 if(this->GeneratorVerbose
)
181 options
|= TAR_VERBOSE
;
186 if (tar_open(&t
, realName
,
191 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem with tar_open(): "
192 << strerror(errno
) << std::endl
);
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
);
214 if (tar_append_eof(t
) != 0)
216 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem with tar_append_eof(): "
217 << strerror(errno
) << std::endl
);
222 if (tar_close(t
) != 0)
224 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem with tar_close(): "
225 << strerror(errno
) << std::endl
);
231 //----------------------------------------------------------------------
232 int cmCPackTarCompress_Compress_Output(void* client_data
,
233 const char* data
, int data_length
)
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
)
246 mydata
->OutputStream
->write(data
, data_length
);
250 //----------------------------------------------------------------------
251 int cmCPackTarCompressGenerator::GenerateHeader(std::ostream
* os
)