summaryrefslogtreecommitdiff
path: root/cpp/src/IcePatch2/Util.cpp
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2009-10-02 09:35:28 -0230
committerDwayne Boone <dwayne@zeroc.com>2009-10-02 09:35:28 -0230
commit6d8d16b3761eaa24c9c754dd0f2cc1a70de8fad0 (patch)
treeff37056717cff166bc705112f54e98074f8d1f40 /cpp/src/IcePatch2/Util.cpp
parent3772. Recovering from Glacier2 / Ice router session failure. (diff)
downloadice-6d8d16b3761eaa24c9c754dd0f2cc1a70de8fad0.tar.bz2
ice-6d8d16b3761eaa24c9c754dd0f2cc1a70de8fad0.tar.xz
ice-6d8d16b3761eaa24c9c754dd0f2cc1a70de8fad0.zip
C++Builder 2010 support
Diffstat (limited to 'cpp/src/IcePatch2/Util.cpp')
-rw-r--r--cpp/src/IcePatch2/Util.cpp1442
1 files changed, 0 insertions, 1442 deletions
diff --git a/cpp/src/IcePatch2/Util.cpp b/cpp/src/IcePatch2/Util.cpp
deleted file mode 100644
index 135ea08ab2c..00000000000
--- a/cpp/src/IcePatch2/Util.cpp
+++ /dev/null
@@ -1,1442 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-//
-// We need to include io.h first to get the proper signature for
-// _wfindfirst
-//
-#ifdef _WIN32
-# include <io.h>
-#endif
-
-#include <IceUtil/DisableWarnings.h>
-#include <IceUtil/IceUtil.h>
-#include <IceUtil/StringUtil.h>
-#include <IceUtil/FileUtil.h>
-#define ICE_PATCH2_API_EXPORTS
-#include <IcePatch2/Util.h>
-#include <openssl/sha.h>
-#include <bzlib.h>
-#include <iomanip>
-
-#ifdef _WIN32
-# include <direct.h>
-#else
-# include <unistd.h>
-# include <dirent.h>
-#endif
-
-#ifdef __BCPLUSPLUS__
-# include <iterator>
-#endif
-
-const char* IcePatch2::checksumFile = "IcePatch2.sum";
-const char* IcePatch2::logFile = "IcePatch2.log";
-
-//
-// Solaris 9 and before doesn't have scandir() or alphasort().
-//
-#ifdef __sun
-
-extern "C" static int
-ice_scandir(const char* dir, struct dirent*** namelist,
- int (*select)(const struct dirent*),
- int (*compar)(const void*, const void*))
-{
- DIR* d;
- struct dirent* entry;
- register int i = 0;
- size_t entrysize;
-
- if((d = opendir(dir)) == 0)
- {
- return -1;
- }
-
- *namelist = 0;
- while((entry = readdir(d)) != 0)
- {
- if(select == 0 || (select != 0 && (*select)(entry)))
- {
- *namelist = (struct dirent**)realloc((void*)(*namelist), (size_t)((i + 1) * sizeof(struct dirent*)));
- if(*namelist == 0)
- {
- closedir(d);
- return -1;
- }
-
- entrysize = sizeof(struct dirent) - sizeof(entry->d_name) + strlen(entry->d_name) + 1;
- (*namelist)[i] = (struct dirent*)malloc(entrysize);
- if((*namelist)[i] == 0)
- {
- closedir(d);
- return -1;
- }
- memcpy((*namelist)[i], entry, entrysize);
- ++i;
- }
- }
-
- if(closedir(d))
- {
- return -1;
- }
-
- if(i == 0)
- {
- return -1;
- }
-
- if(compar != 0)
- {
- qsort((void *)(*namelist), (size_t)i, sizeof(struct dirent *), compar);
- }
-
- return i;
-}
-
-extern "C" static int
-ice_alphasort(const void* v1, const void* v2)
-{
- const struct dirent **a = (const struct dirent **)v1;
- const struct dirent **b = (const struct dirent **)v2;
- return(strcmp((*a)->d_name, (*b)->d_name));
-}
-
-#endif
-
-using namespace std;
-using namespace Ice;
-using namespace IcePatch2;
-
-bool
-IcePatch2::writeFileInfo(FILE* fp, const FileInfo& info)
-{
- int rc = fprintf(fp, "%s\t%s\t%d\t%d\n",
- IceUtilInternal::escapeString(info.path, "").c_str(),
- bytesToString(info.checksum).c_str(),
- info.size,
- static_cast<int>(info.executable));
- return rc > 0;
-}
-
-bool
-IcePatch2::readFileInfo(FILE* fp, FileInfo& 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');
- IceUtilInternal::unescapeString(s, 0, s.size(), info.path);
-
- getline(is, s, '\t');
- info.checksum = stringToBytes(s);
-
- is >> info.size;
- is >> info.executable;
-
- return true;
-}
-
-string
-IcePatch2::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
-IcePatch2::stringToBytes(const string& str)
-{
- ByteSeq bytes;
- bytes.reserve((str.size() + 1) / 2);
-
- for(unsigned int i = 0; i + 1 < str.size(); i += 2)
- {
-/*
- istringstream is(str.substr(i, 2));
- int byte;
- is >> hex >> byte;
-*/
-
- int byte = 0;
-
- for(int 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
-IcePatch2::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 && isalpha(static_cast<unsigned char>(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 && isalpha(static_cast<unsigned char>(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
-IcePatch2::isRoot(const string& pa)
-{
- string path = simplify(pa);
-#ifdef _WIN32
- return path == "/" || path.size() == 3 && isalpha(static_cast<unsigned char>(path[0])) && path[1] == ':' &&
- path[2] == '/';
-#else
- return path == "/";
-#endif
-}
-
-string
-IcePatch2::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
-IcePatch2::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
-IcePatch2::ignoreSuffix(const string& path)
-{
- string suffix = getSuffix(path);
- return suffix == "md5" // For legacy IcePatch.
- || suffix == "tot" // For legacy IcePatch.
- || suffix == "bz2"
- || suffix == "bz2temp";
-}
-
-string
-IcePatch2::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
-IcePatch2::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
-IcePatch2::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 "cannot rename `" + fromPath + "' to `" + toPath + "': " + IceUtilInternal::lastErrorToString();
- }
-}
-
-void
-IcePatch2::remove(const string& pa)
-{
- const string path = simplify(pa);
-
- IceUtilInternal::structstat buf;
- if(IceUtilInternal::stat(path, &buf) == -1)
- {
- throw "cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
- if(S_ISDIR(buf.st_mode))
- {
- if(IceUtilInternal::rmdir(path) == -1)
- {
- if(errno == EACCES)
- {
- assert(false);
- }
- throw "cannot remove directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- }
- else
- {
- if(IceUtilInternal::remove(path) == -1)
- {
- throw "cannot remove file `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- }
-}
-
-void
-IcePatch2::removeRecursive(const string& pa)
-{
- const string path = simplify(pa);
-
- IceUtilInternal::structstat buf;
- if(IceUtilInternal::stat(path, &buf) == -1)
- {
- throw "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 "cannot remove directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- }
- }
- else
- {
- if(IceUtilInternal::remove(path) == -1)
- {
- throw "cannot remove file `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- }
-}
-
-StringSeq
-IcePatch2::readDirectory(const string& pa)
-{
- const string path = simplify(pa);
-
-#ifdef _WIN32
-
- StringSeq result;
- const wstring fs = IceUtil::stringToWstring(simplify(path + "/*"));
-
-# ifdef __BCPLUSPLUS__
- struct _wffblk data;
- int h = _wfindfirst(fs.c_str(), &data, FA_DIREC);
- if(h == -1)
- {
- if(_doserrno == ENMFILE)
- {
- return result;
- }
- throw "cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
-
- while(true)
- {
- string name = IceUtil::wstringToString(data.ff_name);
- assert(!name.empty());
-
- if(name != ".." && name != ".")
- {
- result.push_back(name);
- }
-
- if(_wfindnext(&data) == -1)
- {
- if(errno == ENOENT)
- {
- break;
- }
-
- string ex = "cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- _wfindclose(&data);
- throw ex;
- }
- }
-
- _wfindclose(&data);
-# else
- struct _wfinddata_t data;
-
-# if defined(_MSC_VER) && (_MSC_VER < 1300)
- long h = _wfindfirst(fs.c_str(), &data);
-# else
- intptr_t h = _wfindfirst(fs.c_str(), &data);
-# endif
- if(h == -1)
- {
- throw "cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
- while(true)
- {
- string name = IceUtil::wstringToString(data.name);
- assert(!name.empty());
-
- if(name != ".." && name != ".")
- {
- result.push_back(name);
- }
-
- if(_wfindnext(h, &data) == -1)
- {
- if(errno == ENOENT)
- {
- break;
- }
-
- string ex = "cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- _findclose(h);
- throw ex;
- }
- }
-
- _findclose(h);
-# endif
-
- sort(result.begin(), result.end());
- return result;
-
-#else
-
- struct dirent **namelist;
-#ifdef __sun
- int n = ice_scandir(path.c_str(), &namelist, 0, ice_alphasort);
-#else
- int n = scandir(path.c_str(), &namelist, 0, alphasort);
-#endif
- if(n < 0)
- {
- throw "cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
- StringSeq result;
- result.reserve(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
-IcePatch2::createDirectory(const string& pa)
-{
- const string path = simplify(pa);
-
- if(IceUtilInternal::mkdir(path, 0777) == -1)
- {
- if(errno != EEXIST)
- {
- throw "cannot create directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- }
-}
-
-void
-IcePatch2::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 "cannot create directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- }
- }
-}
-
-void
-IcePatch2::compressBytesToFile(const string& pa, const ByteSeq& bytes, Int pos)
-{
- const string path = simplify(pa);
-
- FILE* stdioFile = IceUtilInternal::fopen(path, "wb");
- if(!stdioFile)
- {
- throw "cannot open `" + path + "' for writing:\n" + IceUtilInternal::lastErrorToString();
- }
-
- int bzError;
- BZFILE* bzFile = BZ2_bzWriteOpen(&bzError, stdioFile, 5, 0, 0);
- if(bzError != BZ_OK)
- {
- string ex = "BZ2_bzWriteOpen failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- fclose(stdioFile);
- throw ex;
- }
-
- BZ2_bzWrite(&bzError, bzFile, const_cast<Byte*>(&bytes[pos]), static_cast<int>(bytes.size() - pos));
- if(bzError != BZ_OK)
- {
- string ex = "BZ2_bzWrite failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
- fclose(stdioFile);
- throw ex;
- }
-
- BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
- if(bzError != BZ_OK)
- {
- string ex = "BZ2_bzWriteClose failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- fclose(stdioFile);
- throw ex;
- }
-
- fclose(stdioFile);
-}
-
-void
-IcePatch2::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 "cannot open `" + path + "' for writing:\n" + IceUtilInternal::lastErrorToString();
- }
-
- stdioFileBZ2 = IceUtilInternal::fopen(pathBZ2, "rb");
- if(!stdioFileBZ2)
- {
- throw "cannot open `" + pathBZ2 + "' for reading:\n" + IceUtilInternal::lastErrorToString();
- }
-
-#ifdef __BCPLUSPLUS__
- //
- // The BZ2_bzReadOpen/BZ2_bzRead/BZ2_bzReadClose functions fail with BCC
- //
- OS::structstat buf;
- if(OS::osstat(pathBZ2, &buf) == -1)
- {
- throw "cannot stat `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
- ByteSeq compressedBytes(buf.st_size);
- if(fread(&compressedBytes[0], buf.st_size, 1, stdioFileBZ2) != 1)
- {
- throw "cannot read from `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
- ByteSeq uncompressedBytes;
- unsigned int uncompressedLen = buf.st_size * 2;
- while(true)
- {
- uncompressedBytes.resize(uncompressedLen);
- int bzError = BZ2_bzBuffToBuffDecompress(&uncompressedBytes[0], &uncompressedLen, &compressedBytes[0],
- buf.st_size, 0, 0);
- if(bzError == BZ_OK)
- {
- break;
- }
- else if(bzError == BZ_OUTBUFF_FULL)
- {
- uncompressedLen *= 2;
- continue;
- }
- else
- {
- string ex = "BZ2_bzBuffToBuffDecompress failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- throw ex;
- }
- }
-
- if(fwrite(&uncompressedBytes[0], uncompressedLen, 1, fp) != 1)
- {
- throw "cannot write to `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
-#else
- bzFile = BZ2_bzReadOpen(&bzError, stdioFileBZ2, 0, 0, 0, 0);
- if(bzError != BZ_OK)
- {
- string ex = "BZ2_bzReadOpen failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- throw ex;
- }
-
- 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 ex = "BZ2_bzRead failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- throw ex;
- }
-
- if(sz > 0)
- {
- long pos = ftell(stdioFileBZ2);
- if(pos == -1)
- {
- throw "cannot get read position for `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
- if(fwrite(bytesBZ2, sz, 1, fp) != 1)
- {
- throw "cannot write to `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- }
- }
-
- BZ2_bzReadClose(&bzError, bzFile);
- bzFile = 0;
- if(bzError != BZ_OK)
- {
- string ex = "BZ2_bzReadClose failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- throw ex;
- }
-#endif
- }
- catch(...)
- {
- if(bzFile != 0)
- {
- BZ2_bzReadClose(&bzError, bzFile);
- }
- if(stdioFileBZ2 != 0)
- {
- fclose(stdioFileBZ2);
- }
- if(fp != 0)
- {
- fclose(fp);
- }
- throw;
- }
-
- fclose(stdioFileBZ2);
- fclose(fp);
-}
-
-void
-IcePatch2::setFileFlags(const string& pa, const FileInfo& info)
-{
-#ifndef _WIN32 // Windows doesn't support the executable flag
- const string path = simplify(pa);
- IceUtilInternal::structstat buf;
- if(IceUtilInternal::stat(path, &buf) == -1)
- {
- throw "cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- chmod(path.c_str(), info.executable ? buf.st_mode | S_IXUSR : buf.st_mode & ~S_IXUSR);
-#endif
-}
-
-static bool
-getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, GetFileInfoSeqCB* cb,
- FileInfoSeq& 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 "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 "cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
- if(S_ISDIR(buf.st_mode))
- {
- FileInfo 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())
- {
- SHA1(reinterpret_cast<unsigned char*>(&bytes[0]), bytes.size(),
- reinterpret_cast<unsigned char*>(&bytesSHA[0]));
- }
- else
- {
- fill(bytesSHA.begin(), bytesSHA.end(), 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(!getFileInfoSeqInt(basePath, simplify(relPath + '/' + *p), compress, cb, infoSeq))
- {
- return false;
- }
- }
- }
- else if(S_ISREG(buf.st_mode))
- {
- FileInfo 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 = static_cast<Int>(bufBZ2.st_size);
- }
- }
-
- if(cb && !cb->checksum(relPath))
- {
- return false;
- }
-
- ByteSeq bytesSHA(20);
-
- if(relPath.size() + buf.st_size == 0)
- {
- fill(bytesSHA.begin(), bytesSHA.end(), 0);
- }
- else
- {
- SHA_CTX ctx;
- SHA1_Init(&ctx);
- if(relPath.size() != 0)
- {
- SHA1_Update(&ctx, reinterpret_cast<const void*>(relPath.c_str()), relPath.size());
- }
-
- if(buf.st_size != 0)
- {
-#ifdef __BCPLUSPLUS__
- //
- // The BZ2_bzWriteOpen/BZ2_bzWrite/BZ2_bzWriteClose functions fail with BCC
- //
- if(doCompress)
- {
- int fd = IceUtilInternal::open(path.c_str(), O_BINARY|O_RDONLY);
- if(fd == -1)
- {
- throw "cannot open `" + path + "' for reading:\n" + IceUtilInternal::lastErrorToString();
- }
-
- ByteSeq uncompressedBytes(buf.st_size);
-
- if(read(fd, &uncompressedBytes[0], buf.st_size) == -1)
- {
- close(fd);
- throw "cannot read from `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
- unsigned int compressedLen = buf.st_size * 1.01 + 600;
- ByteSeq compressedBytes(compressedLen);
-
- int bzError = BZ2_bzBuffToBuffCompress(&compressedBytes[0], &compressedLen,
- &uncompressedBytes[0], buf.st_size, 5, 0, 0);
- if(bzError != BZ_OK)
- {
- string ex = "BZ2_bzBuffToBuffCompress failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- close(fd);
- throw ex;
- }
- close(fd);
-
- const string pathBZ2Temp = path + ".bz2temp";
- FILE* stdioFile = IceUtilInternal::fopen(pathBZ2Temp, "wb");
- if(fwrite(&compressedBytes[0], compressedLen, 1, stdioFile) != 1)
- {
- fclose(stdioFile);
- throw "cannot write to `" + pathBZ2Temp + "':\n" + IceUtilInternal::lastErrorToString();
- }
- fclose(stdioFile);
-
- rename(pathBZ2Temp, pathBZ2);
-
- info.size = compressedLen;
- }
-#endif
-
- int fd = IceUtilInternal::open(path.c_str(), O_BINARY|O_RDONLY);
- if(fd == -1)
- {
- throw "cannot open `" + path + "' for reading:\n" + IceUtilInternal::lastErrorToString();
- }
-
-#ifndef __BCPLUSPLUS__
- const string pathBZ2Temp = path + ".bz2temp";
- FILE* stdioFile = 0;
- int bzError = 0;
- BZFILE* bzFile = 0;
- if(doCompress)
- {
- stdioFile = IceUtilInternal::fopen(simplify(pathBZ2Temp), "wb");
- if(!stdioFile)
- {
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
- _close(fd);
-#else
- close(fd);
-#endif
- throw "cannot open `" + pathBZ2Temp + "' for writing:\n" + IceUtilInternal::lastErrorToString();
- }
-
- bzFile = BZ2_bzWriteOpen(&bzError, stdioFile, 5, 0, 0);
- if(bzError != BZ_OK)
- {
- string ex = "BZ2_bzWriteOpen failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- fclose(stdioFile);
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
- _close(fd);
-#else
- close(fd);
-#endif
- throw ex;
- }
- }
-#endif
-
- unsigned int bytesLeft = static_cast<unsigned int>(buf.st_size);
- while(bytesLeft > 0)
- {
- ByteSeq bytes(min(bytesLeft, 1024u*1024));
- if(
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
- _read(fd, &bytes[0], static_cast<unsigned int>(bytes.size()))
-#else
- read(fd, &bytes[0], static_cast<unsigned int>(bytes.size()))
-#endif
- == -1)
- {
-#ifndef __BCPLUSPLUS__
- if(doCompress)
- {
- fclose(stdioFile);
- }
-#endif
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
- _close(fd);
-#else
- close(fd);
-#endif
- throw "cannot read from `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- bytesLeft -= static_cast<unsigned int>(bytes.size());
-
-#ifndef __BCPLUSPLUS__
- if(doCompress)
- {
- BZ2_bzWrite(&bzError, bzFile, const_cast<Byte*>(&bytes[0]), static_cast<int>(bytes.size()));
- if(bzError != BZ_OK)
- {
- string ex = "BZ2_bzWrite failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
- fclose(stdioFile);
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
- _close(fd);
-#else
- close(fd);
-#endif
- throw ex;
- }
- }
-#endif
-
- SHA1_Update(&ctx, reinterpret_cast<const void*>(&bytes[0]), bytes.size());
- }
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
- _close(fd);
-#else
- close(fd);
-#endif
-
-#ifndef __BCPLUSPLUS__
- if(doCompress)
- {
- BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
- if(bzError != BZ_OK)
- {
- string ex = "BZ2_bzWriteClose failed";
- if(bzError == BZ_IO_ERROR)
- {
- ex += string(": ") + IceUtilInternal::lastErrorToString();
- }
- fclose(stdioFile);
- throw ex;
- }
-
- fclose(stdioFile);
-
- rename(pathBZ2Temp, pathBZ2);
-
- if(IceUtilInternal::stat(pathBZ2, &bufBZ2) == -1)
- {
- throw "cannot stat `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString();
- }
-
- info.size = static_cast<Int>(bufBZ2.st_size);
- }
-#endif
- }
-
- SHA1_Final(reinterpret_cast<unsigned char*>(&bytesSHA[0]), &ctx);
- }
-
- info.checksum.swap(bytesSHA);
-
- infoSeq.push_back(info);
- }
- }
-
- return true;
-}
-
-bool
-IcePatch2::getFileInfoSeq(const string& basePath, int compress, GetFileInfoSeqCB* cb,
- FileInfoSeq& infoSeq)
-{
- return getFileInfoSeqSubDir(basePath, ".", compress, cb, infoSeq);
-}
-
-bool
-IcePatch2::getFileInfoSeqSubDir(const string& basePa, const string& relPa, int compress, GetFileInfoSeqCB* cb,
- FileInfoSeq& infoSeq)
-{
- const string basePath = simplify(basePa);
- const string relPath = simplify(relPa);
-
- if(!getFileInfoSeqInt(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
-IcePatch2::saveFileInfoSeq(const string& pa, const FileInfoSeq& infoSeq)
-{
- {
- const string path = simplify(pa + '/' + checksumFile);
-
- FILE* fp = IceUtilInternal::fopen(path, "w");
- if(!fp)
- {
- throw "cannot open `" + path + "' for writing:\n" + IceUtilInternal::lastErrorToString();
- }
- try
- {
- for(FileInfoSeq::const_iterator p = infoSeq.begin(); p != infoSeq.end(); ++p)
- {
- if(!writeFileInfo(fp, *p))
- {
- throw "error writing `" + path + "':\n" + IceUtilInternal::lastErrorToString();
- }
- }
- }
- catch(...)
- {
- fclose(fp);
- throw;
- }
- fclose(fp);
- }
-
- {
- const string pathLog = simplify(pa + '/' + logFile);
-
- try
- {
- remove(pathLog);
- }
- catch(...)
- {
- }
- }
-}
-
-void
-IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq)
-{
- {
- const string path = simplify(pa + '/' + checksumFile);
-
- FILE* fp = IceUtilInternal::fopen(path, "r");
- if(!fp)
- {
- throw "cannot open `" + path + "' for reading:\n" + IceUtilInternal::lastErrorToString();
- }
-
- while(true)
- {
- FileInfo 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)
- {
- FileInfoSeq remove;
- FileInfoSeq update;
-
- while(true)
- {
- int c = fgetc(fp);
- if(c == EOF)
- {
- break;
- }
-
- FileInfo 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());
-
- FileInfoSeq 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
-IcePatch2::getFileTree0(const FileInfoSeq& 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[i];
-
- tree1.files.clear();
- tree1.checksum.resize(20);
-
- FileInfoSeq::const_iterator p;
-
- for(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(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())
- {
- SHA1(reinterpret_cast<unsigned char*>(&allChecksums1[0]), allChecksums1.size(),
- reinterpret_cast<unsigned char*>(&tree1.checksum[0]));
- }
- else
- {
- fill(tree1.checksum.begin(), tree1.checksum.end(), 0);
- }
-
- copy(tree1.checksum.begin(), tree1.checksum.end(), c0);
- }
-
- if(!allChecksums0.empty())
- {
- SHA1(reinterpret_cast<unsigned char*>(&allChecksums0[0]), allChecksums0.size(),
- reinterpret_cast<unsigned char*>(&tree0.checksum[0]));
- }
- else
- {
- fill(tree0.checksum.begin(), tree0.checksum.end(), 0);
- }
-}
-