cmCPackTarCompressGenerator.cxx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmCPackTarCompressGenerator.h"
  14. #include "cmake.h"
  15. #include "cmGlobalGenerator.h"
  16. #include "cmLocalGenerator.h"
  17. #include "cmSystemTools.h"
  18. #include "cmMakefile.h"
  19. #include "cmGeneratedFileStream.h"
  20. #include "cmCPackLog.h"
  21. #include <cmsys/SystemTools.hxx>
  22. #include <cmcompress/cmcompress.h>
  23. #include <libtar/libtar.h>
  24. #include <memory> // auto_ptr
  25. #include <fcntl.h>
  26. #include <errno.h>
  27. //----------------------------------------------------------------------
  28. class cmCPackTarCompressGeneratorForward
  29. {
  30. public:
  31. static int GenerateHeader(cmCPackTarCompressGenerator* gg, std::ostream* os)
  32. {
  33. return gg->GenerateHeader(os);
  34. }
  35. };
  36. //----------------------------------------------------------------------
  37. cmCPackTarCompressGenerator::cmCPackTarCompressGenerator()
  38. {
  39. }
  40. //----------------------------------------------------------------------
  41. cmCPackTarCompressGenerator::~cmCPackTarCompressGenerator()
  42. {
  43. }
  44. //----------------------------------------------------------------------
  45. class cmCPackTarCompress_Data
  46. {
  47. public:
  48. cmCPackTarCompress_Data(cmCPackTarCompressGenerator* gen) :
  49. OutputStream(0), Generator(gen) {}
  50. std::ostream* OutputStream;
  51. cmCPackTarCompressGenerator* Generator;
  52. cmcompress_stream CMCompressStream;
  53. };
  54. //----------------------------------------------------------------------
  55. extern "C" {
  56. // For cmTar
  57. int cmCPackTarCompress_Data_Open(void *client_data, const char* name,
  58. int oflags, mode_t mode);
  59. ssize_t cmCPackTarCompress_Data_Write(void *client_data, void *buff,
  60. size_t n);
  61. int cmCPackTarCompress_Data_Close(void *client_data);
  62. // For cmCompress
  63. int cmCPackTarCompress_Compress_Output(void* cdata, const char* data,
  64. int len);
  65. }
  66. //----------------------------------------------------------------------
  67. int cmCPackTarCompress_Data_Open(void *client_data, const char* pathname,
  68. int, mode_t)
  69. {
  70. cmCPackTarCompress_Data *mydata = (cmCPackTarCompress_Data*)client_data;
  71. if ( !cmcompress_compress_initialize(&mydata->CMCompressStream) )
  72. {
  73. return -1;
  74. }
  75. mydata->CMCompressStream.client_data = mydata;
  76. mydata->CMCompressStream.output_stream = cmCPackTarCompress_Compress_Output;
  77. cmGeneratedFileStream* gf = new cmGeneratedFileStream;
  78. // Open binary
  79. gf->Open(pathname, false, true);
  80. mydata->OutputStream = gf;
  81. if ( !*mydata->OutputStream )
  82. {
  83. return -1;
  84. }
  85. if ( !cmcompress_compress_start(&mydata->CMCompressStream) )
  86. {
  87. return -1;
  88. }
  89. if ( !cmCPackTarCompressGeneratorForward::GenerateHeader(
  90. mydata->Generator,gf))
  91. {
  92. return -1;
  93. }
  94. return 0;
  95. }
  96. //----------------------------------------------------------------------
  97. ssize_t cmCPackTarCompress_Data_Write(void *client_data, void *buff, size_t n)
  98. {
  99. cmCPackTarCompress_Data *mydata = (cmCPackTarCompress_Data*)client_data;
  100. if ( !cmcompress_compress(&mydata->CMCompressStream, buff, n) )
  101. {
  102. return 0;
  103. }
  104. return n;
  105. }
  106. //----------------------------------------------------------------------
  107. int cmCPackTarCompress_Data_Close(void *client_data)
  108. {
  109. cmCPackTarCompress_Data *mydata = (cmCPackTarCompress_Data*)client_data;
  110. if ( !cmcompress_compress_finalize(&mydata->CMCompressStream) )
  111. {
  112. delete mydata->OutputStream;
  113. return -1;
  114. }
  115. delete mydata->OutputStream;
  116. mydata->OutputStream = 0;
  117. return (0);
  118. }
  119. //----------------------------------------------------------------------
  120. int cmCPackTarCompressGenerator::InitializeInternal()
  121. {
  122. this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
  123. return this->Superclass::InitializeInternal();
  124. }
  125. //----------------------------------------------------------------------
  126. int cmCPackTarCompressGenerator::CompressFiles(const char* outFileName,
  127. const char* toplevel, const std::vector<std::string>& files)
  128. {
  129. cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
  130. << (toplevel ? toplevel : "(NULL)") << std::endl);
  131. cmCPackTarCompress_Data mydata(this);
  132. TAR *t;
  133. char buf[TAR_MAXPATHLEN];
  134. char pathname[TAR_MAXPATHLEN];
  135. tartype_t compressType = {
  136. (openfunc_t)cmCPackTarCompress_Data_Open,
  137. (closefunc_t)cmCPackTarCompress_Data_Close,
  138. (readfunc_t)0,
  139. (writefunc_t)cmCPackTarCompress_Data_Write,
  140. &mydata
  141. };
  142. // Ok, this libtar is not const safe. for now use auto_ptr hack
  143. char* realName = new char[ strlen(outFileName) + 1 ];
  144. std::auto_ptr<char> realNamePtr(realName);
  145. strcpy(realName, outFileName);
  146. int flags = O_WRONLY | O_CREAT;
  147. int options = 0;
  148. if(this->GeneratorVerbose)
  149. {
  150. options |= TAR_VERBOSE;
  151. }
  152. #ifdef __CYGWIN__
  153. options |= TAR_GNU;
  154. #endif
  155. if (tar_open(&t, realName,
  156. &compressType,
  157. flags, 0644,
  158. options) == -1)
  159. {
  160. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_open(): "
  161. << strerror(errno) << std::endl);
  162. return 0;
  163. }
  164. std::vector<std::string>::const_iterator fileIt;
  165. for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
  166. {
  167. std::string rp = cmSystemTools::RelativePath(toplevel, fileIt->c_str());
  168. strncpy(pathname, fileIt->c_str(), sizeof(pathname));
  169. pathname[sizeof(pathname)-1] = 0;
  170. strncpy(buf, rp.c_str(), sizeof(buf));
  171. buf[sizeof(buf)-1] = 0;
  172. if (tar_append_tree(t, pathname, buf) != 0)
  173. {
  174. cmCPackLogger(cmCPackLog::LOG_ERROR,
  175. "Problem with tar_append_tree(\"" << buf << "\", \""
  176. << pathname << "\"): "
  177. << strerror(errno) << std::endl);
  178. tar_close(t);
  179. return 0;
  180. }
  181. }
  182. if (tar_append_eof(t) != 0)
  183. {
  184. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_append_eof(): "
  185. << strerror(errno) << std::endl);
  186. tar_close(t);
  187. return 0;
  188. }
  189. if (tar_close(t) != 0)
  190. {
  191. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with tar_close(): "
  192. << strerror(errno) << std::endl);
  193. return 0;
  194. }
  195. return 1;
  196. }
  197. //----------------------------------------------------------------------
  198. int cmCPackTarCompress_Compress_Output(void* client_data,
  199. const char* data, int data_length)
  200. {
  201. if(!client_data)
  202. {
  203. return 0;
  204. }
  205. cmcompress_stream *cstream = static_cast<cmcompress_stream*>(client_data);
  206. cmCPackTarCompress_Data *mydata
  207. = static_cast<cmCPackTarCompress_Data*>(cstream->client_data);
  208. if ( !mydata->OutputStream )
  209. {
  210. return 0;
  211. }
  212. mydata->OutputStream->write(data, data_length);
  213. return data_length;
  214. }
  215. //----------------------------------------------------------------------
  216. int cmCPackTarCompressGenerator::GenerateHeader(std::ostream* os)
  217. {
  218. (void)os;
  219. return 1;
  220. }