diff options
-rw-r--r-- | Source/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Source/cmCryptoHash.cxx | 90 | ||||
-rw-r--r-- | Source/cmCryptoHash.h | 40 | ||||
-rw-r--r-- | Source/cmSystemTools.cxx | 57 |
4 files changed, 139 insertions, 50 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ba41d98..284c84d 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -129,6 +129,8 @@ SET(SRCS cmComputeLinkInformation.h cmComputeTargetDepends.h cmComputeTargetDepends.cxx + cmCryptoHash.cxx + cmCryptoHash.h cmCustomCommand.cxx cmCustomCommand.h cmCustomCommandGenerator.cxx diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx new file mode 100644 index 0000000..3a73398 --- /dev/null +++ b/Source/cmCryptoHash.cxx @@ -0,0 +1,90 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmCryptoHash.h" + +#include <cmsys/MD5.h> + +//---------------------------------------------------------------------------- +std::string cmCryptoHash::HashString(const char* input) +{ + this->Initialize(); + this->Append(reinterpret_cast<unsigned char const*>(input), + static_cast<int>(strlen(input))); + return this->Finalize(); +} + +//---------------------------------------------------------------------------- +std::string cmCryptoHash::HashFile(const char* file) +{ + std::ifstream fin(file, std::ios::in | cmsys_ios_binary); + if(!fin) + { + return ""; + } + + this->Initialize(); + + // Should be efficient enough on most system: + const int bufferSize = 4096; + char buffer[bufferSize]; + unsigned char const* buffer_uc = + reinterpret_cast<unsigned char const*>(buffer); + // This copy loop is very sensitive on certain platforms with + // slightly broken stream libraries (like HPUX). Normally, it is + // incorrect to not check the error condition on the fin.read() + // before using the data, but the fin.gcount() will be zero if an + // error occurred. Therefore, the loop should be safe everywhere. + while(fin) + { + fin.read(buffer, bufferSize); + if(int gcount = static_cast<int>(fin.gcount())) + { + this->Append(buffer_uc, gcount); + } + } + if(fin.eof()) + { + return this->Finalize(); + } + return ""; +} + +//---------------------------------------------------------------------------- +cmCryptoHashMD5::cmCryptoHashMD5(): MD5(cmsysMD5_New()) +{ +} + +//---------------------------------------------------------------------------- +cmCryptoHashMD5::~cmCryptoHashMD5() +{ + cmsysMD5_Delete(this->MD5); +} + +//---------------------------------------------------------------------------- +void cmCryptoHashMD5::Initialize() +{ + cmsysMD5_Initialize(this->MD5); +} + +//---------------------------------------------------------------------------- +void cmCryptoHashMD5::Append(unsigned char const* buf, int sz) +{ + cmsysMD5_Append(this->MD5, buf, sz); +} + +//---------------------------------------------------------------------------- +std::string cmCryptoHashMD5::Finalize() +{ + char md5out[32]; + cmsysMD5_FinalizeHex(this->MD5, md5out); + return std::string(md5out, 32); +} diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h new file mode 100644 index 0000000..670624c --- /dev/null +++ b/Source/cmCryptoHash.h @@ -0,0 +1,40 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmCryptoHash_h +#define cmCryptoHash_h + +#include "cmStandardIncludes.h" + +class cmCryptoHash +{ +public: + std::string HashString(const char* input); + std::string HashFile(const char* file); +protected: + virtual void Initialize()=0; + virtual void Append(unsigned char const*, int)=0; + virtual std::string Finalize()=0; +}; + +class cmCryptoHashMD5: public cmCryptoHash +{ + struct cmsysMD5_s* MD5; +public: + cmCryptoHashMD5(); + ~cmCryptoHashMD5(); +protected: + virtual void Initialize(); + virtual void Append(unsigned char const* buf, int sz); + virtual std::string Finalize(); +}; + +#endif diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 03364bd..8eec1e2 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -54,7 +54,7 @@ #if defined(CMAKE_BUILD_WITH_CMAKE) # include <memory> // auto_ptr # include <fcntl.h> -# include <cmsys/MD5.h> +# include "cmCryptoHash.h" #endif #if defined(CMAKE_USE_ELF_PARSER) @@ -1197,48 +1197,10 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname) bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out) { #if defined(CMAKE_BUILD_WITH_CMAKE) - if(!cmSystemTools::FileExists(source)) - { - return false; - } - - // Open files -#if defined(_WIN32) || defined(__CYGWIN__) - cmsys_ios::ifstream fin(source, cmsys_ios::ios::binary | cmsys_ios::ios::in); -#else - cmsys_ios::ifstream fin(source); -#endif - if(!fin) - { - return false; - } - - cmsysMD5* md5 = cmsysMD5_New(); - cmsysMD5_Initialize(md5); - - // Should be efficient enough on most system: - const int bufferSize = 4096; - char buffer[bufferSize]; - unsigned char const* buffer_uc = - reinterpret_cast<unsigned char const*>(buffer); - // This copy loop is very sensitive on certain platforms with - // slightly broken stream libraries (like HPUX). Normally, it is - // incorrect to not check the error condition on the fin.read() - // before using the data, but the fin.gcount() will be zero if an - // error occurred. Therefore, the loop should be safe everywhere. - while(fin) - { - fin.read(buffer, bufferSize); - if(int gcount = static_cast<int>(fin.gcount())) - { - cmsysMD5_Append(md5, buffer_uc, gcount); - } - } - cmsysMD5_FinalizeHex(md5, md5out); - cmsysMD5_Delete(md5); - - fin.close(); - return true; + cmCryptoHashMD5 md5; + std::string str = md5.HashFile(source); + strncpy(md5out, str.c_str(), 32); + return !str.empty(); #else (void)source; (void)md5out; @@ -1250,13 +1212,8 @@ bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out) std::string cmSystemTools::ComputeStringMD5(const char* input) { #if defined(CMAKE_BUILD_WITH_CMAKE) - char md5out[32]; - cmsysMD5* md5 = cmsysMD5_New(); - cmsysMD5_Initialize(md5); - cmsysMD5_Append(md5, reinterpret_cast<unsigned char const*>(input), -1); - cmsysMD5_FinalizeHex(md5, md5out); - cmsysMD5_Delete(md5); - return std::string(md5out, 32); + cmCryptoHashMD5 md5; + return md5.HashString(input); #else (void)input; cmSystemTools::Message("md5sum not supported in bootstrapping mode","Error"); |