cmCPackTGZGenerator.cxx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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 "cmCPackTGZGenerator.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 <cmsys/SystemTools.hxx>
  21. #include <cmzlib/zlib.h>
  22. #include <libtar/libtar.h>
  23. #include <memory> // auto_ptr
  24. #include <fcntl.h>
  25. #include <errno.h>
  26. //----------------------------------------------------------------------
  27. class cmCPackTGZGeneratorForward
  28. {
  29. public:
  30. static int GenerateHeader(cmCPackTGZGenerator* gg, std::ostream* os)
  31. {
  32. return gg->GenerateHeader(os);
  33. }
  34. };
  35. //----------------------------------------------------------------------
  36. cmCPackTGZGenerator::cmCPackTGZGenerator()
  37. {
  38. }
  39. //----------------------------------------------------------------------
  40. cmCPackTGZGenerator::~cmCPackTGZGenerator()
  41. {
  42. }
  43. //----------------------------------------------------------------------
  44. int cmCPackTGZGenerator::ProcessGenerator()
  45. {
  46. return this->Superclass::ProcessGenerator();
  47. }
  48. //----------------------------------------------------------------------
  49. int cmCPackTGZGenerator::Initialize(const char* name)
  50. {
  51. return this->Superclass::Initialize(name);
  52. }
  53. //----------------------------------------------------------------------
  54. class cmCPackTGZ_Data
  55. {
  56. public:
  57. cmCPackTGZ_Data(cmCPackTGZGenerator* gen) :
  58. Name(0), OutputStream(0), Generator(gen) {}
  59. const char *Name;
  60. std::ostream* OutputStream;
  61. cmCPackTGZGenerator* Generator;
  62. };
  63. extern "C" {
  64. int cmCPackTGZ_Data_Open(void *client_data, const char* name, int oflags, mode_t mode);
  65. ssize_t cmCPackTGZ_Data_Write(void *client_data, void *buff, size_t n);
  66. int cmCPackTGZ_Data_Close(void *client_data);
  67. }
  68. //----------------------------------------------------------------------
  69. int cmCPackTGZ_Data_Open(void *client_data, const char* pathname, int, mode_t)
  70. {
  71. cmCPackTGZ_Data *mydata = (cmCPackTGZ_Data*)client_data;
  72. cmGeneratedFileStream* gf = new cmGeneratedFileStream(pathname);
  73. mydata->OutputStream = gf;
  74. if ( !*mydata->OutputStream )
  75. {
  76. return -1;
  77. }
  78. gf->SetCompression(true);
  79. gf->SetCompressionExtraExtension(false);
  80. if ( !cmCPackTGZGeneratorForward::GenerateHeader(mydata->Generator,mydata->OutputStream))
  81. {
  82. return -1;
  83. }
  84. return 0;
  85. }
  86. //----------------------------------------------------------------------
  87. ssize_t cmCPackTGZ_Data_Write(void *client_data, void *buff, size_t n)
  88. {
  89. cmCPackTGZ_Data *mydata = (cmCPackTGZ_Data*)client_data;
  90. mydata->OutputStream->write(reinterpret_cast<const char*>(buff), n);
  91. if ( !*mydata->OutputStream )
  92. {
  93. return 0;
  94. }
  95. return n;
  96. }
  97. //----------------------------------------------------------------------
  98. int cmCPackTGZ_Data_Close(void *client_data)
  99. {
  100. cmCPackTGZ_Data *mydata = (cmCPackTGZ_Data*)client_data;
  101. delete mydata->OutputStream;
  102. mydata->OutputStream = 0;
  103. return (0);
  104. }
  105. //----------------------------------------------------------------------
  106. int cmCPackTGZGenerator::CompressFiles(const char* outFileName, const char* toplevel,
  107. const std::vector<std::string>& files)
  108. {
  109. std::cout << "Toplevel: " << toplevel << std::endl;
  110. cmCPackTGZ_Data mydata(this);
  111. TAR *t;
  112. char buf[TAR_MAXPATHLEN];
  113. char pathname[TAR_MAXPATHLEN];
  114. tartype_t gztype = {
  115. (openfunc_t)cmCPackTGZ_Data_Open,
  116. (closefunc_t)cmCPackTGZ_Data_Close,
  117. (readfunc_t)0,
  118. (writefunc_t)cmCPackTGZ_Data_Write,
  119. &mydata
  120. };
  121. // Ok, this libtar is not const safe. for now use auto_ptr hack
  122. char* realName = new char[ strlen(outFileName) + 1 ];
  123. std::auto_ptr<char> realNamePtr(realName);
  124. strcpy(realName, outFileName);
  125. int flags = O_WRONLY | O_CREAT;
  126. if (tar_open(&t, realName,
  127. &gztype,
  128. flags, 0644,
  129. (m_GeneratorVerbose?TAR_VERBOSE:0)
  130. | 0) == -1)
  131. {
  132. cmSystemTools::Error("Problem with tar_open(): ", strerror(errno));
  133. return 0;
  134. }
  135. std::vector<std::string>::const_iterator fileIt;
  136. for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
  137. {
  138. strncpy(pathname, fileIt->c_str(), sizeof(pathname));
  139. pathname[sizeof(pathname)-1] = 0;
  140. strncpy(buf, pathname, sizeof(buf));
  141. buf[sizeof(buf)-1] = 0;
  142. if (tar_append_tree(t, buf, pathname) != 0)
  143. {
  144. cmOStringStream ostr;
  145. ostr << "Problem with tar_append_tree(\"" << buf << "\", \"" << pathname << "\"): "
  146. << strerror(errno);
  147. cmSystemTools::Error(ostr.str().c_str());
  148. tar_close(t);
  149. return 0;
  150. }
  151. }
  152. if (tar_append_eof(t) != 0)
  153. {
  154. cmSystemTools::Error("Problem with tar_append_eof(): ", strerror(errno));
  155. tar_close(t);
  156. return 0;
  157. }
  158. if (tar_close(t) != 0)
  159. {
  160. cmSystemTools::Error("Problem with tar_close(): ", strerror(errno));
  161. return 0;
  162. }
  163. return 1;
  164. }
  165. //----------------------------------------------------------------------
  166. int cmCPackTGZGenerator::GenerateHeader(std::ostream* os)
  167. {
  168. (void)os;
  169. return 1;
  170. }