1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmCPackTarBZip2Generator.cxx,v $
6 Date: $Date: 2007-02-02 21:52:20 $
7 Version: $Revision: 1.4 $
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 "cmCPackTarBZip2Generator.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>
30 // Includes needed for implementation of RenameFile. This is not in
31 // system tools because it is not implemented robustly enough to move
32 // files across directories.
35 # include <sys/stat.h>
38 //----------------------------------------------------------------------
39 cmCPackTarBZip2Generator::cmCPackTarBZip2Generator()
41 this->Compress
= false;
44 //----------------------------------------------------------------------
45 cmCPackTarBZip2Generator::~cmCPackTarBZip2Generator()
49 //----------------------------------------------------------------------
50 int cmCPackTarBZip2Generator::InitializeInternal()
52 this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
53 std::vector
<std::string
> path
;
54 std::string pkgPath
= cmSystemTools::FindProgram("bzip2", path
, false);
55 if ( pkgPath
.empty() )
57 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Cannot find BZip2" << std::endl
);
60 this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath
.c_str());
61 cmCPackLogger(cmCPackLog::LOG_VERBOSE
, "Found Compress program: "
65 return this->Superclass::InitializeInternal();
68 //----------------------------------------------------------------------
69 int cmCPackTarBZip2Generator::BZip2File(const char* packageDirFileName
)
72 cmOStringStream dmgCmd1
;
73 dmgCmd1
<< "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
74 << "\" \"" << packageDirFileName
78 int res
= cmSystemTools::RunSingleCommand(dmgCmd1
.str().c_str(), &output
,
79 &retVal
, 0, this->GeneratorVerbose
, 0);
82 std::string tmpFile
= this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
83 tmpFile
+= "/CompressBZip2.log";
84 cmGeneratedFileStream
ofs(tmpFile
.c_str());
85 ofs
<< "# Run command: " << dmgCmd1
.str().c_str() << std::endl
86 << "# Output:" << std::endl
87 << output
.c_str() << std::endl
;
88 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem running BZip2 command: "
89 << dmgCmd1
.str().c_str() << std::endl
90 << "Please check " << tmpFile
.c_str() << " for errors" << std::endl
);
96 //----------------------------------------------------------------------
97 int cmCPackTarBZip2Generator::CompressFiles(const char* outFileName
,
98 const char* toplevel
, const std::vector
<std::string
>& files
)
100 std::string packageDirFileName
101 = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
102 packageDirFileName
+= ".tar";
104 if ( !this->Superclass::CompressFiles(packageDirFileName
.c_str(),
110 if(!this->BZip2File(packageDirFileName
.c_str()))
115 std::string compressOutFile
= packageDirFileName
+ ".bz2";
116 if ( !cmSystemTools::SameFile(compressOutFile
.c_str(), outFileName
) )
118 if ( !this->RenameFile(compressOutFile
.c_str(), outFileName
) )
120 cmCPackLogger(cmCPackLog::LOG_ERROR
, "Problem renaming: \""
121 << compressOutFile
.c_str() << "\" to \""
122 << (outFileName
? outFileName
: "(NULL)") << std::endl
);
130 //----------------------------------------------------------------------------
131 int cmCPackTarBZip2Generator::RenameFile(const char* oldname
,
135 /* On Windows the move functions will not replace existing files.
136 Check if the destination exists. */
138 if(stat(newname
, &newFile
) == 0)
140 /* The destination exists. We have to replace it carefully. The
141 MoveFileEx function does what we need but is not available on
146 /* Make sure the destination is not read only. */
147 attrs
= GetFileAttributes(newname
);
148 if(attrs
& FILE_ATTRIBUTE_READONLY
)
150 SetFileAttributes(newname
, attrs
& ~FILE_ATTRIBUTE_READONLY
);
153 /* Check the windows version number. */
154 osv
.dwOSVersionInfoSize
= sizeof(osv
);
156 if(osv
.dwPlatformId
== VER_PLATFORM_WIN32_WINDOWS
)
158 /* This is Win9x. There is no MoveFileEx implementation. We
159 cannot quite rename the file atomically. Just delete the
160 destination and then move the file. */
162 return MoveFile(oldname
, newname
);
166 /* This is not Win9x. Use the MoveFileEx implementation. */
167 return MoveFileEx(oldname
, newname
, MOVEFILE_REPLACE_EXISTING
);
172 /* The destination does not exist. Just move the file. */
173 return MoveFile(oldname
, newname
);
176 /* On UNIX we have an OS-provided call to do this atomically. */
177 return rename(oldname
, newname
) == 0;