cmCPackTarBZip2Generator.cxx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmCPackTarBZip2Generator.h"
  11. #include "cmake.h"
  12. #include "cmGlobalGenerator.h"
  13. #include "cmLocalGenerator.h"
  14. #include "cmSystemTools.h"
  15. #include "cmMakefile.h"
  16. #include "cmGeneratedFileStream.h"
  17. #include "cmCPackLog.h"
  18. #include <cmsys/SystemTools.hxx>
  19. // Includes needed for implementation of RenameFile. This is not in
  20. // system tools because it is not implemented robustly enough to move
  21. // files across directories.
  22. #ifdef _WIN32
  23. # include <windows.h>
  24. # include <sys/stat.h>
  25. #endif
  26. //----------------------------------------------------------------------
  27. cmCPackTarBZip2Generator::cmCPackTarBZip2Generator()
  28. {
  29. this->Compress = false;
  30. }
  31. //----------------------------------------------------------------------
  32. cmCPackTarBZip2Generator::~cmCPackTarBZip2Generator()
  33. {
  34. }
  35. //----------------------------------------------------------------------
  36. int cmCPackTarBZip2Generator::InitializeInternal()
  37. {
  38. this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
  39. std::vector<std::string> path;
  40. std::string pkgPath = cmSystemTools::FindProgram("bzip2", path, false);
  41. if ( pkgPath.empty() )
  42. {
  43. cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find BZip2" << std::endl);
  44. return 0;
  45. }
  46. this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath.c_str());
  47. cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Found Compress program: "
  48. << pkgPath.c_str()
  49. << std::endl);
  50. return this->Superclass::InitializeInternal();
  51. }
  52. //----------------------------------------------------------------------
  53. int cmCPackTarBZip2Generator::BZip2File(const char* packageDirFileName)
  54. {
  55. int retVal = 0;
  56. cmOStringStream dmgCmd1;
  57. dmgCmd1 << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
  58. << "\" \"" << packageDirFileName
  59. << "\"";
  60. retVal = -1;
  61. std::string output;
  62. int res = cmSystemTools::RunSingleCommand(dmgCmd1.str().c_str(), &output,
  63. &retVal, 0, this->GeneratorVerbose, 0);
  64. if ( !res || retVal )
  65. {
  66. std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
  67. tmpFile += "/CompressBZip2.log";
  68. cmGeneratedFileStream ofs(tmpFile.c_str());
  69. ofs << "# Run command: " << dmgCmd1.str().c_str() << std::endl
  70. << "# Output:" << std::endl
  71. << output.c_str() << std::endl;
  72. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running BZip2 command: "
  73. << dmgCmd1.str().c_str() << std::endl
  74. << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
  75. return 0;
  76. }
  77. return 1;
  78. }
  79. //----------------------------------------------------------------------
  80. int cmCPackTarBZip2Generator::CompressFiles(const char* outFileName,
  81. const char* toplevel, const std::vector<std::string>& files)
  82. {
  83. std::string packageDirFileName
  84. = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
  85. packageDirFileName += ".tar";
  86. std::string output;
  87. if ( !this->Superclass::CompressFiles(packageDirFileName.c_str(),
  88. toplevel, files) )
  89. {
  90. return 0;
  91. }
  92. if(!this->BZip2File(packageDirFileName.c_str()))
  93. {
  94. return 0;
  95. }
  96. std::string compressOutFile = packageDirFileName + ".bz2";
  97. if ( !cmSystemTools::SameFile(compressOutFile.c_str(), outFileName ) )
  98. {
  99. if ( !this->RenameFile(compressOutFile.c_str(), outFileName) )
  100. {
  101. cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem renaming: \""
  102. << compressOutFile.c_str() << "\" to \""
  103. << (outFileName ? outFileName : "(NULL)") << std::endl);
  104. return 0;
  105. }
  106. }
  107. return 1;
  108. }
  109. //----------------------------------------------------------------------------
  110. int cmCPackTarBZip2Generator::RenameFile(const char* oldname,
  111. const char* newname)
  112. {
  113. #ifdef _WIN32
  114. /* On Windows the move functions will not replace existing files.
  115. Check if the destination exists. */
  116. struct stat newFile;
  117. if(stat(newname, &newFile) == 0)
  118. {
  119. /* The destination exists. We have to replace it carefully. The
  120. MoveFileEx function does what we need but is not available on
  121. Win9x. */
  122. OSVERSIONINFO osv;
  123. DWORD attrs;
  124. /* Make sure the destination is not read only. */
  125. attrs = GetFileAttributes(newname);
  126. if(attrs & FILE_ATTRIBUTE_READONLY)
  127. {
  128. SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
  129. }
  130. /* Check the windows version number. */
  131. osv.dwOSVersionInfoSize = sizeof(osv);
  132. GetVersionEx(&osv);
  133. if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  134. {
  135. /* This is Win9x. There is no MoveFileEx implementation. We
  136. cannot quite rename the file atomically. Just delete the
  137. destination and then move the file. */
  138. DeleteFile(newname);
  139. return MoveFile(oldname, newname);
  140. }
  141. else
  142. {
  143. /* This is not Win9x. Use the MoveFileEx implementation. */
  144. return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING);
  145. }
  146. }
  147. else
  148. {
  149. /* The destination does not exist. Just move the file. */
  150. return MoveFile(oldname, newname);
  151. }
  152. #else
  153. /* On UNIX we have an OS-provided call to do this atomically. */
  154. return rename(oldname, newname) == 0;
  155. #endif
  156. }