diff options
Diffstat (limited to 'cpp/src/IcePatch2Lib/Util.cpp')
-rw-r--r-- | cpp/src/IcePatch2Lib/Util.cpp | 1240 |
1 files changed, 0 insertions, 1240 deletions
diff --git a/cpp/src/IcePatch2Lib/Util.cpp b/cpp/src/IcePatch2Lib/Util.cpp deleted file mode 100644 index 6080dd44558..00000000000 --- a/cpp/src/IcePatch2Lib/Util.cpp +++ /dev/null @@ -1,1240 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -// -// We need to include io.h first to get the proper signature for -// _wfindfirst -// -#ifdef _WIN32 -# include <io.h> -#endif - -#include <IceUtil/IceUtil.h> -#include <IceUtil/StringUtil.h> -#include <IceUtil/FileUtil.h> -#include <Ice/SHA1.h> -#include <IceUtil/Exception.h> -#include <IcePatch2Lib/Util.h> -#include <IcePatch2/FileServer.h> -#include <bzlib.h> -#include <iomanip> - -#ifdef _WIN32 -# include <direct.h> -#else -# include <unistd.h> -# include <dirent.h> -#endif - -#include <iterator> - -// Ignore macOS OpenSSL deprecation warnings -#ifdef __APPLE__ -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -const char* IcePatch2Internal::checksumFile = "IcePatch2.sum"; -const char* IcePatch2Internal::logFile = "IcePatch2.log"; - -using namespace std; -using namespace Ice; -using namespace IcePatch2; -using namespace IcePatch2Internal; - -FileInfo -IcePatch2Internal::toFileInfo(const LargeFileInfo& largeInfo) -{ - if(largeInfo.size > 0x7FFFFFFF) - { - ostringstream os; - os << "cannot encode size `" << largeInfo.size << "' for file `" << largeInfo.path << "' as Ice::Int" << endl; - throw FileSizeRangeException(os.str()); - } - - FileInfo info; - info.path = largeInfo.path; - info.checksum = largeInfo.checksum; - info.size = static_cast<Ice::Int>(largeInfo.size), - info.executable = largeInfo.executable; - - return info; -} - -LargeFileInfo -IcePatch2Internal::toLargeFileInfo(const FileInfo& info) -{ - LargeFileInfo largeInfo; - largeInfo.path = info.path; - largeInfo.checksum = info.checksum; - largeInfo.size = info.size; - largeInfo.executable = info.executable; - return largeInfo; -} - -bool -IcePatch2Internal::writeFileInfo(FILE* fp, const LargeFileInfo& info) -{ - int rc = fprintf(fp, "%s\t%s\t" ICE_INT64_FORMAT "\t%d\n", - escapeString(info.path, "", IceUtilInternal::Compat).c_str(), - bytesToString(info.checksum).c_str(), - info.size, - static_cast<int>(info.executable)); - return rc > 0; -} - -bool -IcePatch2Internal::readFileInfo(FILE* fp, LargeFileInfo& info) -{ - string data; - char buf[BUFSIZ]; - while(fgets(buf, static_cast<int>(sizeof(buf)), fp) != 0) - { - data += buf; - - size_t len = strlen(buf); - if(buf[len - 1] == '\n') - { - break; - } - } - if(data.empty()) - { - return false; - } - - istringstream is(data); - - string s; - getline(is, s, '\t'); - try - { - info.path = IceUtilInternal::unescapeString(s, 0, s.size(), ""); - } - catch(const IceUtil::IllegalArgumentException& ex) - { - throw invalid_argument(ex.reason()); - } - - getline(is, s, '\t'); - info.checksum = stringToBytes(s); - - is >> info.size; - is >> info.executable; - - return true; -} - -string -IcePatch2Internal::bytesToString(const ByteSeq& bytes) -{ -/* - ostringstream s; - - for(ByteSeq::const_iterator p = bytes.begin(); p != bytes.end(); ++p) - { - s << setw(2) << setfill('0') << hex << static_cast<int>(*p); - } - - return s.str(); -*/ - - static const char* toHex = "0123456789abcdef"; - - string s; - s.resize(bytes.size() * 2); - - for(unsigned int i = 0; i < bytes.size(); ++i) - { - s[i * 2] = toHex[(bytes[i] >> 4) & 0xf]; - s[i * 2 + 1] = toHex[bytes[i] & 0xf]; - } - - return s; -} - -ByteSeq -IcePatch2Internal::stringToBytes(const string& str) -{ - ByteSeq bytes; - bytes.reserve((str.size() + 1) / 2); - - for(size_t i = 0; i + 1 < str.size(); i += 2) - { -/* - istringstream is(str.substr(i, 2)); - int byte; - is >> hex >> byte; -*/ - - int byte = 0; - - for(size_t j = 0; j < 2; ++j) - { - char c = str[i + j]; - - if(c >= '0' && c <= '9') - { - byte |= c - '0'; - } - else if(c >= 'a' && c <= 'f') - { - byte |= 10 + c - 'a'; - } - else if(c >= 'A' && c <= 'F') - { - byte |= 10 + c - 'A'; - } - - if(j == 0) - { - byte <<= 4; - } - } - - bytes.push_back(static_cast<Byte>(byte)); - } - - return bytes; -} - -string -IcePatch2Internal::simplify(const string& path) -{ - string result = path; - - string::size_type pos; - -#ifdef _WIN32 - pos = 0; - if(result.find("\\\\") == 0) - { - pos = 2; - } - - for(; pos < result.size(); ++pos) - { - if(result[pos] == '\\') - { - result[pos] = '/'; - } - } -#endif - - pos = 0; - while((pos = result.find("//", pos)) != string::npos) - { - result.erase(pos, 1); - } - - pos = 0; - while((pos = result.find("/./", pos)) != string::npos) - { - result.erase(pos, 2); - } - - while(result.substr(0, 4) == "/../") - { - result.erase(0, 3); - } - - if(result.substr(0, 2) == "./") - { - result.erase(0, 2); - } - - if(result == "/." || - (result.size() == 4 && IceUtilInternal::isAlpha(result[0]) && result[1] == ':' && - result[2] == '/' && result[3] == '.')) - { - return result.substr(0, result.size() - 1); - } - - if(result.size() >= 2 && result.substr(result.size() - 2, 2) == "/.") - { - result.erase(result.size() - 2, 2); - } - - if(result == "/" || (result.size() == 3 && IceUtilInternal::isAlpha(result[0]) && result[1] == ':' && - result[2] == '/')) - { - return result; - } - - if(result.size() >= 1 && result[result.size() - 1] == '/') - { - result.erase(result.size() - 1); - } - - if(result == "/..") - { - result = "/"; - } - - return result; -} - -bool -IcePatch2Internal::isRoot(const string& pa) -{ - string path = simplify(pa); -#ifdef _WIN32 - return path == "/" || path.size() == 3 && IceUtilInternal::isAlpha(path[0]) && path[1] == ':' && - path[2] == '/'; -#else - return path == "/"; -#endif -} - -string -IcePatch2Internal::getSuffix(const string& pa) -{ - const string path = simplify(pa); - - string::size_type dotPos = path.rfind('.'); - string::size_type slashPos = path.rfind('/'); - - if(dotPos == string::npos || (slashPos != string::npos && slashPos > dotPos)) - { - return string(); - } - - return path.substr(dotPos + 1); -} - -string -IcePatch2Internal::getWithoutSuffix(const string& pa) -{ - const string path = simplify(pa); - - string::size_type dotPos = path.rfind('.'); - string::size_type slashPos = path.rfind('/'); - - if(dotPos == string::npos || (slashPos != string::npos && slashPos > dotPos)) - { - return path; - } - - return path.substr(0, dotPos); -} - -bool -IcePatch2Internal::ignoreSuffix(const string& path) -{ - string suffix = getSuffix(path); - return suffix == "md5" // For legacy IcePatch. - || suffix == "tot" // For legacy IcePatch. - || suffix == "bz2" - || suffix == "bz2temp"; -} - -string -IcePatch2Internal::getBasename(const string& pa) -{ - const string path = simplify(pa); - - string::size_type pos = path.rfind('/'); - if(pos == string::npos) - { - return path; - } - else - { - return path.substr(pos + 1); - } -} - -string -IcePatch2Internal::getDirname(const string& pa) -{ - const string path = simplify(pa); - - string::size_type pos = path.rfind('/'); - if(pos == string::npos) - { - return string(); - } - else - { - return path.substr(0, pos); - } -} - -void -IcePatch2Internal::rename(const string& fromPa, const string& toPa) -{ - - const string fromPath = simplify(fromPa); - const string toPath = simplify(toPa); - - IceUtilInternal::remove(toPath); // We ignore errors, as the file we are renaming to might not exist. - if(IceUtilInternal::rename(fromPath, toPath) == -1) - { - throw runtime_error("cannot rename `" + fromPath + "' to `" + toPath + "': " + IceUtilInternal::lastErrorToString()); - } -} - -void -IcePatch2Internal::remove(const string& pa) -{ - const string path = simplify(pa); - - IceUtilInternal::structstat buf; - if(IceUtilInternal::stat(path, &buf) == -1) - { - throw runtime_error("cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - - if(S_ISDIR(buf.st_mode)) - { - if(IceUtilInternal::rmdir(path) == -1) - { - if(errno == EACCES) - { - assert(false); - } - throw runtime_error("cannot remove directory `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - } - else - { - if(IceUtilInternal::remove(path) == -1) - { - throw runtime_error("cannot remove file `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - } -} - -void -IcePatch2Internal::removeRecursive(const string& pa) -{ - const string path = simplify(pa); - - IceUtilInternal::structstat buf; - if(IceUtilInternal::stat(path, &buf) == -1) - { - throw runtime_error("cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - - if(S_ISDIR(buf.st_mode)) - { - StringSeq paths = readDirectory(path); - for(StringSeq::const_iterator p = paths.begin(); p != paths.end(); ++p) - { - removeRecursive(path + '/' + *p); - } - - if(!isRoot(path)) - { - if(IceUtilInternal::rmdir(path) == -1) - { - throw runtime_error("cannot remove directory `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - } - } - else - { - if(IceUtilInternal::remove(path) == -1) - { - throw runtime_error("cannot remove file `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - } -} - -StringSeq -IcePatch2Internal::readDirectory(const string& pa) -{ - const string path = simplify(pa); - -#ifdef _WIN32 - - // - // IcePatch2 doesn't support to use string converters, so don't need to use - // any string converter in stringToWstring or wstringToString conversions. - // - StringSeq result; - const wstring fs = IceUtil::stringToWstring(simplify(path + "/*")); - - struct _wfinddata_t data; - intptr_t h = _wfindfirst(fs.c_str(), &data); - if(h == -1) - { - throw runtime_error("cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - - while(true) - { - string name = wstringToString(data.name); - assert(!name.empty()); - - if(name != ".." && name != ".") - { - result.push_back(name); - } - - if(_wfindnext(h, &data) == -1) - { - if(errno == ENOENT) - { - break; - } - string reason = "cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString(); - _findclose(h); - throw runtime_error(reason); - } - } - - _findclose(h); - - sort(result.begin(), result.end()); - return result; - -#else - - struct dirent **namelist; - int n = scandir(path.c_str(), &namelist, 0, alphasort); - - if(n < 0) - { - throw runtime_error("cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - - StringSeq result; - assert(n >= 2); - result.reserve(static_cast<size_t>(n - 2)); - - for(int i = 0; i < n; ++i) - { - string name = namelist[i]->d_name; - assert(!name.empty()); - - free(namelist[i]); - - if(name != ".." && name != ".") - { - result.push_back(name); - } - } - - free(namelist); - return result; - -#endif -} - -void -IcePatch2Internal::createDirectory(const string& pa) -{ - const string path = simplify(pa); - - if(IceUtilInternal::mkdir(path, 0777) == -1) - { - if(errno != EEXIST) - { - throw runtime_error("cannot create directory `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - } -} - -void -IcePatch2Internal::createDirectoryRecursive(const string& pa) -{ - const string path = simplify(pa); - - string dir = getDirname(path); - if(!dir.empty()) - { - createDirectoryRecursive(dir); - } - - if(!isRoot(path + "/")) - { - IceUtilInternal::structstat buf; - if(IceUtilInternal::stat(path, &buf) != -1) - { - if(S_ISDIR(buf.st_mode)) - { - return; - } - } - - if(IceUtilInternal::mkdir(path, 0777) == -1) - { - if(errno != EEXIST) - { - throw runtime_error("cannot create directory `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - } - } -} - -void -IcePatch2Internal::compressBytesToFile(const string& pa, const ByteSeq& bytes, Int pos) -{ - const string path = simplify(pa); - - FILE* stdioFile = IceUtilInternal::fopen(path, "wb"); - if(!stdioFile) - { - throw runtime_error("cannot open `" + path + "' for writing:\n" + IceUtilInternal::lastErrorToString()); - } - - int bzError; - BZFILE* bzFile = BZ2_bzWriteOpen(&bzError, stdioFile, 5, 0, 0); - if(bzError != BZ_OK) - { - string reason = "BZ2_bzWriteOpen failed"; - if(bzError == BZ_IO_ERROR) - { - reason += ": " + IceUtilInternal::lastErrorToString(); - } - fclose(stdioFile); - throw runtime_error(reason); - } - - BZ2_bzWrite(&bzError, bzFile, const_cast<Byte*>(&bytes[static_cast<size_t>(pos)]), - static_cast<int>(bytes.size()) - pos); - if(bzError != BZ_OK) - { - string reason = "BZ2_bzWrite failed"; - if(bzError == BZ_IO_ERROR) - { - reason += ": " + IceUtilInternal::lastErrorToString(); - } - BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0); - fclose(stdioFile); - throw runtime_error(reason); - } - - BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0); - if(bzError != BZ_OK) - { - string reason = "BZ2_bzWriteClose failed"; - if(bzError == BZ_IO_ERROR) - { - reason += ": " + IceUtilInternal::lastErrorToString(); - } - fclose(stdioFile); - throw runtime_error(reason); - } - - fclose(stdioFile); -} - -void -IcePatch2Internal::decompressFile(const string& pa) -{ - const string path = simplify(pa); - const string pathBZ2 = path + ".bz2"; - - FILE* fp = 0; - FILE* stdioFileBZ2 = 0; - int bzError; - BZFILE* bzFile = 0; - - try - { - fp = IceUtilInternal::fopen(path, "wb"); - if(!fp) - { - throw runtime_error("cannot open `" + path + "' for writing:\n" + IceUtilInternal::lastErrorToString()); - } - - stdioFileBZ2 = IceUtilInternal::fopen(pathBZ2, "rb"); - if(!stdioFileBZ2) - { - throw runtime_error("cannot open `" + pathBZ2 + "' for reading:\n" + IceUtilInternal::lastErrorToString()); - } - - bzFile = BZ2_bzReadOpen(&bzError, stdioFileBZ2, 0, 0, 0, 0); - if(bzError != BZ_OK) - { - string reason = "BZ2_bzReadOpen failed"; - if(bzError == BZ_IO_ERROR) - { - reason += ": " + IceUtilInternal::lastErrorToString(); - } - throw runtime_error(reason); - } - - const Int numBZ2 = 64 * 1024; - Byte bytesBZ2[numBZ2]; - - while(bzError != BZ_STREAM_END) - { - int sz = BZ2_bzRead(&bzError, bzFile, bytesBZ2, numBZ2); - if(bzError != BZ_OK && bzError != BZ_STREAM_END) - { - string reason = "BZ2_bzRead failed"; - if(bzError == BZ_IO_ERROR) - { - reason += ": " + IceUtilInternal::lastErrorToString(); - } - throw runtime_error(reason); - } - - if(sz > 0) - { - long pos = ftell(stdioFileBZ2); - if(pos == -1) - { - throw runtime_error("cannot get read position for `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString()); - } - - if(fwrite(bytesBZ2, static_cast<size_t>(sz), 1, fp) != 1) - { - throw runtime_error("cannot write to `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - } - } - - BZ2_bzReadClose(&bzError, bzFile); - bzFile = 0; - if(bzError != BZ_OK) - { - string reason = "BZ2_bzReadClose failed"; - if(bzError == BZ_IO_ERROR) - { - reason += ": " + IceUtilInternal::lastErrorToString(); - } - throw runtime_error(reason); - } - } - catch(...) - { - if(bzFile != 0) - { - BZ2_bzReadClose(&bzError, bzFile); - } - if(stdioFileBZ2 != 0) - { - fclose(stdioFileBZ2); - } - if(fp != 0) - { - fclose(fp); - } - throw; - } - - fclose(stdioFileBZ2); - fclose(fp); -} - -#ifndef _WIN32 -void -IcePatch2Internal::setFileFlags(const string& pa, const LargeFileInfo& info) -{ - const string path = simplify(pa); - IceUtilInternal::structstat buf; - if(IceUtilInternal::stat(path, &buf) == -1) - { - throw runtime_error("cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - chmod(path.c_str(), info.executable ? buf.st_mode | S_IXUSR : buf.st_mode & ~S_IXUSR); -} -#else // Windows doesn't support the executable flag -void -IcePatch2Internal::setFileFlags(const string&, const LargeFileInfo&) -{ -} -#endif - -namespace -{ - -static bool -getFileInfoSeqInternal(const string& basePath, const string& relPath, int compress, GetFileInfoSeqCB* cb, - LargeFileInfoSeq& infoSeq) -{ - if(relPath == checksumFile || relPath == logFile) - { - return true; - } - - const string path = simplify(basePath + '/' + relPath); - - if(ignoreSuffix(path)) - { - const string pathWithoutSuffix = getWithoutSuffix(path); - - if(ignoreSuffix(pathWithoutSuffix)) - { - if(cb && !cb->remove(relPath)) - { - return false; - } - - remove(path); // Removing file with suffix for another file that already has a suffix. - } - else - { - IceUtilInternal::structstat buf; - if(IceUtilInternal::stat(getWithoutSuffix(path), &buf) == -1) - { - if(errno == ENOENT) - { - if(cb && !cb->remove(relPath)) - { - return false; - } - - remove(path); // Removing orphaned file. - } - else - { - throw runtime_error("cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - } - else if(buf.st_size == 0) - { - if(cb && !cb->remove(relPath)) - { - return false; - } - - remove(path); // Removing file with suffix for empty file. - } - } - } - else - { - - IceUtilInternal::structstat buf; - if(IceUtilInternal::stat(path, &buf) == -1) - { - throw runtime_error("cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - - if(S_ISDIR(buf.st_mode)) - { - LargeFileInfo info; - info.path = relPath; - info.size = -1; - info.executable = false; - - ByteSeq bytes(relPath.size()); - copy(relPath.begin(), relPath.end(), bytes.begin()); - - ByteSeq bytesSHA(20); - if(!bytes.empty()) - { - IceInternal::sha1(reinterpret_cast<unsigned char*>(&bytes[0]), bytes.size(), bytesSHA); - } - else - { - fill(bytesSHA.begin(), bytesSHA.end(), Byte(0)); - } - info.checksum.swap(bytesSHA); - - infoSeq.push_back(info); - - StringSeq content = readDirectory(path); - for(StringSeq::const_iterator p = content.begin(); p != content.end() ; ++p) - { - if(!getFileInfoSeqInternal(basePath, simplify(relPath + '/' + *p), compress, cb, infoSeq)) - { - return false; - } - } - } - else if(S_ISREG(buf.st_mode)) - { - LargeFileInfo info; - info.path = relPath; - info.size = 0; -#ifdef _WIN32 - info.executable = false; // Windows doesn't support the executable flag -#else - info.executable = buf.st_mode & S_IXUSR; -#endif - - IceUtilInternal::structstat bufBZ2; - const string pathBZ2 = path + ".bz2"; - bool doCompress = false; - if(buf.st_size != 0 && compress > 0) - { - // - // compress == 0: Never compress. - // compress == 1: Compress if necessary. - // compress >= 2: Always compress. - // - if(compress >= 2 || IceUtilInternal::stat(pathBZ2, &bufBZ2) == -1 || buf.st_mtime >= bufBZ2.st_mtime) - { - if(cb && !cb->compress(relPath)) - { - return false; - } - - doCompress = true; - } - else - { - info.size = bufBZ2.st_size; - } - } - - if(cb && !cb->checksum(relPath)) - { - return false; - } - - ByteSeq bytesSHA; - - if(relPath.size() == 0 && buf.st_size == 0) - { - bytesSHA.resize(20); - fill(bytesSHA.begin(), bytesSHA.end(), Byte(0)); - } - else - { - IceInternal::SHA1 hasher; - if(relPath.size() != 0) - { - hasher.update(reinterpret_cast<const IceUtil::Byte*>(relPath.c_str()), relPath.size()); - } - - if(buf.st_size != 0) - { - int fd = IceUtilInternal::open(path.c_str(), O_BINARY|O_RDONLY); - if(fd == -1) - { - throw runtime_error("cannot open `" + path + "' for reading:\n" + IceUtilInternal::lastErrorToString()); - } - - const string pathBZ2Temp = path + ".bz2temp"; - FILE* stdioFile = 0; - int bzError = 0; - BZFILE* bzFile = 0; - if(doCompress) - { - stdioFile = IceUtilInternal::fopen(simplify(pathBZ2Temp), "wb"); - if(!stdioFile) - { - IceUtilInternal::close(fd); - throw runtime_error("cannot open `" + pathBZ2Temp + "' for writing:\n" + IceUtilInternal::lastErrorToString()); - } - - bzFile = BZ2_bzWriteOpen(&bzError, stdioFile, 5, 0, 0); - if(bzError != BZ_OK) - { - string reason = "BZ2_bzWriteOpen failed"; - if(bzError == BZ_IO_ERROR) - { - reason += ": " + IceUtilInternal::lastErrorToString(); - } - fclose(stdioFile); - IceUtilInternal::close(fd); - throw runtime_error(reason); - } - } - - size_t bytesLeft = static_cast<size_t>(buf.st_size); - while(bytesLeft > 0) - { - ByteSeq bytes(min(bytesLeft, static_cast<size_t>(1024 * 1024))); - if( -#if defined(_MSC_VER) - _read(fd, &bytes[0], static_cast<unsigned int>(bytes.size())) -#else - read(fd, &bytes[0], static_cast<unsigned int>(bytes.size())) -#endif - == -1) - { - if(doCompress) - { - fclose(stdioFile); - } - - IceUtilInternal::close(fd); - throw runtime_error("cannot read from `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - bytesLeft -= static_cast<unsigned int>(bytes.size()); - if(doCompress) - { - BZ2_bzWrite(&bzError, bzFile, const_cast<Byte*>(&bytes[0]), static_cast<int>(bytes.size())); - if(bzError != BZ_OK) - { - string reason = "BZ2_bzWrite failed"; - if(bzError == BZ_IO_ERROR) - { - reason += ": " + IceUtilInternal::lastErrorToString(); - } - BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0); - fclose(stdioFile); - IceUtilInternal::close(fd); - throw runtime_error(reason); - } - } - - hasher.update(reinterpret_cast<IceUtil::Byte*>(&bytes[0]), bytes.size()); - } - - IceUtilInternal::close(fd); - - if(doCompress) - { - BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0); - if(bzError != BZ_OK) - { - string reason = "BZ2_bzWriteClose failed"; - if(bzError == BZ_IO_ERROR) - { - reason += ": " + IceUtilInternal::lastErrorToString(); - } - fclose(stdioFile); - throw runtime_error(reason); - } - - fclose(stdioFile); - - rename(pathBZ2Temp, pathBZ2); - - if(IceUtilInternal::stat(pathBZ2, &bufBZ2) == -1) - { - throw runtime_error("cannot stat `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString()); - } - - info.size = bufBZ2.st_size; - } - } - hasher.finalize(bytesSHA); - } - - info.checksum.swap(bytesSHA); - - infoSeq.push_back(info); - } - } - - return true; -} - -} - -IcePatch2Internal::GetFileInfoSeqCB::~GetFileInfoSeqCB() -{ - // Out of line to avoid weak vtable -} - -bool -IcePatch2Internal::getFileInfoSeq(const string& basePath, int compress, GetFileInfoSeqCB* cb, - LargeFileInfoSeq& infoSeq) -{ - return getFileInfoSeqSubDir(basePath, ".", compress, cb, infoSeq); -} - -bool -IcePatch2Internal::getFileInfoSeqSubDir(const string& basePa, const string& relPa, int compress, GetFileInfoSeqCB* cb, - LargeFileInfoSeq& infoSeq) -{ - const string basePath = simplify(basePa); - const string relPath = simplify(relPa); - - if(!getFileInfoSeqInternal(basePath, relPath, compress, cb, infoSeq)) - { - return false; - } - - sort(infoSeq.begin(), infoSeq.end(), FileInfoLess()); - infoSeq.erase(unique(infoSeq.begin(), infoSeq.end(), FileInfoEqual()), infoSeq.end()); - - return true; -} - -void -IcePatch2Internal::saveFileInfoSeq(const string& pa, const LargeFileInfoSeq& infoSeq) -{ - { - const string path = simplify(pa + '/' + checksumFile); - FILE* fp = IceUtilInternal::fopen(path, "w"); - if(!fp) - { - throw runtime_error("cannot open `" + path + "' for writing:\n" + IceUtilInternal::lastErrorToString()); - } - try - { - for(LargeFileInfoSeq::const_iterator p = infoSeq.begin(); p != infoSeq.end(); ++p) - { - if(!writeFileInfo(fp, *p)) - { - throw runtime_error("error writing `" + path + "':\n" + IceUtilInternal::lastErrorToString()); - } - } - } - catch(...) - { - fclose(fp); - throw; - } - fclose(fp); - } - - { - const string pathLog = simplify(pa + '/' + logFile); - - try - { - remove(pathLog); - } - catch(...) - { - } - } -} - -void -IcePatch2Internal::loadFileInfoSeq(const string& pa, LargeFileInfoSeq& infoSeq) -{ - { - const string path = simplify(pa + '/' + checksumFile); - - FILE* fp = IceUtilInternal::fopen(path, "r"); - if(!fp) - { - throw runtime_error("cannot open `" + path + "' for reading:\n" + IceUtilInternal::lastErrorToString()); - } - - while(true) - { - LargeFileInfo info; - if(readFileInfo(fp, info)) - { - infoSeq.push_back(info); - } - else - { - break; - } - } - fclose(fp); - - sort(infoSeq.begin(), infoSeq.end(), FileInfoLess()); - infoSeq.erase(unique(infoSeq.begin(), infoSeq.end(), FileInfoEqual()), infoSeq.end()); - } - - { - const string pathLog = simplify(pa + '/' + logFile); - - FILE* fp = IceUtilInternal::fopen(pathLog, "r"); - if(fp != 0) - { - LargeFileInfoSeq remove; - LargeFileInfoSeq update; - - while(true) - { - int c = fgetc(fp); - if(c == EOF) - { - break; - } - - LargeFileInfo info; - if(!readFileInfo(fp, info)) - { - break; - } - - if(c == '-') - { - remove.push_back(info); - } - else if(c == '+') - { - update.push_back(info); - } - } - fclose(fp); - - sort(remove.begin(), remove.end(), FileInfoLess()); - remove.erase(unique(remove.begin(), remove.end(), FileInfoEqual()), remove.end()); - - sort(update.begin(), update.end(), FileInfoLess()); - update.erase(unique(update.begin(), update.end(), FileInfoEqual()), update.end()); - - LargeFileInfoSeq newInfoSeq; - newInfoSeq.reserve(infoSeq.size()); - - set_difference(infoSeq.begin(), - infoSeq.end(), - remove.begin(), - remove.end(), - back_inserter(newInfoSeq), - FileInfoLess()); - - infoSeq.swap(newInfoSeq); - - newInfoSeq.clear(); - newInfoSeq.reserve(infoSeq.size()); - - set_union(infoSeq.begin(), - infoSeq.end(), - update.begin(), - update.end(), - back_inserter(newInfoSeq), - FileInfoLess()); - - infoSeq.swap(newInfoSeq); - - saveFileInfoSeq(pa, infoSeq); - } - } -} - -void -IcePatch2Internal::getFileTree0(const LargeFileInfoSeq& infoSeq, FileTree0& tree0) -{ - tree0.nodes.resize(256); - tree0.checksum.resize(20); - - ByteSeq allChecksums0; - allChecksums0.resize(256 * 20); - ByteSeq::iterator c0 = allChecksums0.begin(); - - for(int i = 0; i < 256; ++i, c0 += 20) - { - FileTree1& tree1 = tree0.nodes[static_cast<size_t>(i)]; - - tree1.files.clear(); - tree1.checksum.resize(20); - - for(LargeFileInfoSeq::const_iterator p = infoSeq.begin(); p != infoSeq.end(); ++p) - { - if(i == static_cast<int>(p->checksum[0])) - { - tree1.files.push_back(*p); - } - } - - ByteSeq allChecksums1; - allChecksums1.resize(tree1.files.size() * 21); // 20 bytes for the checksum + 1 byte for the flag - ByteSeq::iterator c1 = allChecksums1.begin(); - - for(LargeFileInfoSeq::const_iterator p = tree1.files.begin(); p != tree1.files.end(); ++p, c1 += 21) - { - copy(p->checksum.begin(), p->checksum.end(), c1); - *(c1 + 20) = p->executable; - } - - if(!allChecksums1.empty()) - { - IceInternal::sha1(reinterpret_cast<unsigned char*>(&allChecksums1[0]), allChecksums1.size(), tree1.checksum); - } - else - { - fill(tree1.checksum.begin(), tree1.checksum.end(), Byte(0)); - } - - copy(tree1.checksum.begin(), tree1.checksum.end(), c0); - } - - if(!allChecksums0.empty()) - { - IceInternal::sha1(reinterpret_cast<unsigned char*>(&allChecksums0[0]), allChecksums0.size(), tree0.checksum); - } - else - { - fill(tree0.checksum.begin(), tree0.checksum.end(), Byte(0)); - } -} |