summaryrefslogtreecommitdiff
path: root/cpp/src/IcePatch/Util.cpp
diff options
context:
space:
mode:
authorMarc Laukien <marc@zeroc.com>2002-04-15 19:12:57 +0000
committerMarc Laukien <marc@zeroc.com>2002-04-15 19:12:57 +0000
commit5f30d7093499c65b10a8458cf68cf9a585262236 (patch)
treeb6ae5af4b1ac7ba89c383bdfd3cb8486fd44e737 /cpp/src/IcePatch/Util.cpp
parentAdded PrivateKeyException to the addKeyCert methods to ensure that the (diff)
downloadice-5f30d7093499c65b10a8458cf68cf9a585262236.tar.bz2
ice-5f30d7093499c65b10a8458cf68cf9a585262236.tar.xz
ice-5f30d7093499c65b10a8458cf68cf9a585262236.zip
added pw check to glacier
Diffstat (limited to 'cpp/src/IcePatch/Util.cpp')
-rw-r--r--cpp/src/IcePatch/Util.cpp1376
1 files changed, 688 insertions, 688 deletions
diff --git a/cpp/src/IcePatch/Util.cpp b/cpp/src/IcePatch/Util.cpp
index 2b61340faca..473b36ed53d 100644
--- a/cpp/src/IcePatch/Util.cpp
+++ b/cpp/src/IcePatch/Util.cpp
@@ -1,688 +1,688 @@
-// **********************************************************************
-//
-// Copyright (c) 2002
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IcePatch/Util.h>
-#include <fstream>
-#include <sys/stat.h>
-#include <openssl/md5.h>
-#include <bzlib.h>
-
-#ifndef _WIN32
-# include <unistd.h>
-# include <dirent.h>
-#else
-# include <direct.h>
-# include <io.h>
-# define S_ISDIR(mode) ((mode) & _S_IFDIR)
-# define S_ISREG(mode) ((mode) & _S_IFREG)
-#endif
-
-using namespace std;
-using namespace Ice;
-using namespace IcePatch;
-
-string
-normalizePath(const string& path)
-{
- string result = path;
-
- string::size_type pos;
-
- for (pos = 0; pos < result.size(); ++pos)
- {
- if (result[pos] == '\\')
- {
- result[pos] = '/';
- }
- }
-
- 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);
- }
-
- if (result.substr(0, 2) == "./")
- {
- result.erase(0, 2);
- }
-
- return result;
-}
-
-string
-IcePatch::identityToPath(const Identity& ident)
-{
- assert(ident.category == "IcePatch");
- return normalizePath(ident.name);
-}
-
-Identity
-IcePatch::pathToIdentity(const string& path)
-{
- Identity ident;
- ident.category = "IcePatch";
- ident.name = normalizePath(path);
- return ident;
-}
-
-string
-IcePatch::getSuffix(const string& path)
-{
- string::size_type pos = path.rfind('.');
- if (pos == string::npos)
- {
- return string();
- }
- else
- {
- return path.substr(pos + 1);
- }
-}
-
-bool
-IcePatch::ignoreSuffix(const string& path)
-{
- string suffix = getSuffix(path);
- return suffix == "md5" || suffix == "md5temp" || suffix == "bz2" || suffix == "bz2temp";
-}
-
-string
-IcePatch::removeSuffix(const string& path)
-{
- string::size_type pos = path.rfind('.');
- if (pos == string::npos)
- {
- return path;
- }
- else
- {
- return path.substr(0, pos);
- }
-}
-
-FileInfo
-IcePatch::getFileInfo(const string& path, bool exceptionIfNotExist)
-{
- struct stat buf;
- if (::stat(path.c_str(), &buf) == -1)
- {
- if (!exceptionIfNotExist && errno == ENOENT)
- {
- FileInfo result;
- result.size = 0;
- result.time = 0;
- result.type = FileTypeNotExist;
- return result;
- }
- else
- {
- FileAccessException ex;
- ex.reason = "cannot stat `" + path + "': " + strerror(errno);
- throw ex;
- }
- }
-
- FileInfo result;
- result.size = buf.st_size;
- result.time = buf.st_mtime;
-
- if (S_ISDIR(buf.st_mode))
- {
- result.type = FileTypeDirectory;
- }
- else if (S_ISREG(buf.st_mode))
- {
- result.type = FileTypeRegular;
- }
- else
- {
- result.type = FileTypeUnknown;
- }
-
- return result;
-}
-
-void
-IcePatch::removeRecursive(const string& path)
-{
- if (getFileInfo(path, true).type == FileTypeDirectory)
- {
- StringSeq paths = readDirectory(path);
- for (StringSeq::const_iterator p = paths.begin(); p != paths.end(); ++p)
- {
- removeRecursive(*p);
- }
- }
-
- if (::remove(path.c_str()) == -1)
- {
- FileAccessException ex;
- ex.reason = "cannot remove file `" + path + "': " + strerror(errno);
- throw ex;
- }
-}
-
-void
-IcePatch::changeDirectory(const string& path)
-{
-#ifdef _WIN32
- if (_chdir(path.c_str()) == -1)
-#else
- if (chdir(path.c_str()) == -1)
-#endif
- {
- FileAccessException ex;
- ex.reason = "cannot change to directory `" + path + "': " + strerror(errno);
- throw ex;
- }
-}
-
-StringSeq
-IcePatch::readDirectory(const string& path)
-{
-#ifdef _WIN32
-
- struct _finddata_t data;
- long h = _findfirst((path + "/*").c_str(), &data);
- if (h == -1)
- {
- FileAccessException ex;
- ex.reason = "cannot read directory `" + path + "': " + strerror(errno);
- throw ex;
- }
-
- StringSeq result;
-
- while (true)
- {
- string name = data.name;
-
- if (name != ".." && name != ".")
- {
- result.push_back(normalizePath(path + '/' + name));
- }
-
- if (_findnext(h, &data) == -1)
- {
- if (errno == ENOENT)
- {
- break;
- }
-
- FileAccessException ex;
- ex.reason = "cannot read directory `" + path + "': " + strerror(errno);
- _findclose(h);
- throw ex;
- }
- }
-
- _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)
- {
- FileAccessException ex;
- ex.reason = "cannot read directory `" + path + "': " + strerror(errno);
- throw ex;
- }
-
- StringSeq result;
- result.reserve(n - 2);
-
- for (int i = 0; i < n; ++i)
- {
- string name = namelist[i]->d_name;
-
- free(namelist[i]);
-
- if (name != ".." && name != ".")
- {
- result.push_back(normalizePath(path + '/' + name));
- }
- }
-
- free(namelist);
- return result;
-
-#endif
-}
-
-void
-IcePatch::createDirectory(const string& path)
-{
-#ifdef _WIN32
- if (::_mkdir(path.c_str()) == -1)
-#else
- if (::mkdir(path.c_str(), 00777) == -1)
-#endif
- {
- FileAccessException ex;
- ex.reason = "cannot create directory `" + path + "': " + strerror(errno);
- throw ex;
- }
-}
-
-ByteSeq
-IcePatch::getMD5(const string& path)
-{
- string pathMD5 = path + ".md5";
- ifstream fileMD5(pathMD5.c_str(), ios::binary);
- if (!fileMD5)
- {
- FileAccessException ex;
- ex.reason = "cannot open `" + pathMD5 + "' for reading: " + strerror(errno);
- throw ex;
- }
- ByteSeq bytesMD5;
- bytesMD5.resize(16);
- fileMD5.read(&bytesMD5[0], 16);
- if (!fileMD5)
- {
- FileAccessException ex;
- ex.reason = "cannot read `" + pathMD5 + "': " + strerror(errno);
- throw ex;
- }
- if (fileMD5.gcount() < 16)
- {
- FileAccessException ex;
- ex.reason = "could not read 16 bytes from `" + pathMD5 + "'";
- throw ex;
- }
- fileMD5.close();
- return bytesMD5;
-}
-
-void
-IcePatch::createMD5(const string& path)
-{
- FileInfo info = getFileInfo(path, true);
- assert(info.type == FileTypeRegular);
-
- //
- // Read the original file.
- //
- ifstream file(path.c_str(), ios::binary);
- if (!file)
- {
- FileAccessException ex;
- ex.reason = "cannot open `" + path + "' for reading: " + strerror(errno);
- throw ex;
- }
- ByteSeq bytes;
- bytes.resize(info.size);
- file.read(&bytes[0], bytes.size());
- if (!file)
- {
- FileAccessException ex;
- ex.reason = "cannot read `" + path + "': " + strerror(errno);
- throw ex;
- }
- if (file.gcount() < static_cast<int>(bytes.size()))
- {
- FileAccessException ex;
- ex.reason = "could not read all bytes from `" + path + "'";
- throw ex;
- }
- file.close();
-
- //
- // Create the MD5 hash value.
- //
- ByteSeq bytesMD5;
- bytesMD5.resize(16);
- MD5(reinterpret_cast<unsigned char*>(&bytes[0]), bytes.size(), reinterpret_cast<unsigned char*>(&bytesMD5[0]));
-
- //
- // Save the MD5 hash value to a temporary MD5 file.
- //
- string pathMD5 = path + ".md5";
- string pathMD5Temp = path + ".md5temp";
- ofstream fileMD5(pathMD5Temp.c_str(), ios::binary);
- if (!fileMD5)
- {
- FileAccessException ex;
- ex.reason = "cannot open `" + pathMD5Temp + "' for writing: " + strerror(errno);
- throw ex;
- }
- fileMD5.write(&bytesMD5[0], 16);
- if (!fileMD5)
- {
- FileAccessException ex;
- ex.reason = "cannot write `" + pathMD5Temp + "': " + strerror(errno);
- throw ex;
- }
- fileMD5.close();
-
- //
- // Rename the temporary MD5 file to the final MD5 file. This is
- // done so that there can be no partial MD5 files after an
- // abortive application termination.
- //
- ::remove(pathMD5.c_str());
- if (::rename(pathMD5Temp.c_str(), pathMD5.c_str()) == -1)
- {
- FileAccessException ex;
- ex.reason = "cannot rename `" + pathMD5Temp + "' to `" + pathMD5 + "': " + strerror(errno);
- throw ex;
- }
-}
-
-ByteSeq
-IcePatch::getBZ2(const string& path, Int pos, Int num)
-{
- string pathBZ2 = path + ".bz2";
- ifstream fileBZ2(pathBZ2.c_str(), ios::binary);
- if (!fileBZ2)
- {
- FileAccessException ex;
- ex.reason = "cannot open `" + pathBZ2 + "' for reading: " + strerror(errno);
- throw ex;
- }
- fileBZ2.seekg(pos);
- if (!fileBZ2)
- {
- FileAccessException ex;
- ostringstream out;
- out << "cannot seek position " << pos << " in file `" << path << "':" << strerror(errno);
- ex.reason = out.str();
- throw ex;
- }
- ByteSeq bytesBZ2;
- bytesBZ2.resize(num);
- fileBZ2.read(&bytesBZ2[0], bytesBZ2.size());
- if (!fileBZ2 && !fileBZ2.eof())
- {
- FileAccessException ex;
- ex.reason = "cannot read `" + pathBZ2 + "': " + strerror(errno);
- throw ex;
- }
- bytesBZ2.resize(fileBZ2.gcount());
- fileBZ2.close();
- return bytesBZ2;
-}
-
-void
-IcePatch::createBZ2(const string& path)
-{
- FileInfo info = getFileInfo(path, true);
- assert(info.type == FileTypeRegular);
-
- //
- // Read the original file in blocks and write a temporary BZ2
- // file.
- //
- ifstream file(path.c_str(), ios::binary);
- if (!file)
- {
- FileAccessException ex;
- ex.reason = "cannot open `" + path + "' for reading: " + strerror(errno);
- throw ex;
- }
-
- string pathBZ2 = path + ".bz2";
- string pathBZ2Temp = path + ".bz2temp";
- FILE* stdioFileBZ2 = fopen(pathBZ2Temp.c_str(), "wb");
- if (!stdioFileBZ2)
- {
- FileAccessException ex;
- ex.reason = "cannot open `" + pathBZ2Temp + "' for writing: " + strerror(errno);
- throw ex;
- }
-
- int bzError;
- BZFILE* bzFile = BZ2_bzWriteOpen(&bzError, stdioFileBZ2, 5, 0, 0);
- if (bzError != BZ_OK)
- {
- FileAccessException ex;
- ex.reason = "BZ2_bzWriteOpen failed";
- if (bzError == BZ_IO_ERROR)
- {
- ex.reason += string(": ") + strerror(errno);
- }
- fclose(stdioFileBZ2);
- throw ex;
- }
-
- static const Int num = 64 * 1024;
- Byte bytes[num];
-
- while (!file.eof())
- {
- file.read(bytes, num);
- if (!file && !file.eof())
- {
- FileAccessException ex;
- ex.reason = "cannot read `" + path + "': " + strerror(errno);
- BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
- fclose(stdioFileBZ2);
- throw ex;
- }
-
- if (file.gcount() > 0)
- {
- BZ2_bzWrite(&bzError, bzFile, bytes, file.gcount());
- if (bzError != BZ_OK)
- {
- FileAccessException ex;
- ex.reason = "BZ2_bzWrite failed";
- if (bzError == BZ_IO_ERROR)
- {
- ex.reason += string(": ") + strerror(errno);
- }
- BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
- fclose(stdioFileBZ2);
- throw ex;
- }
- }
- }
-
- BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
- if (bzError != BZ_OK)
- {
- FileAccessException ex;
- ex.reason = "BZ2_bzWriteClose failed";
- if (bzError == BZ_IO_ERROR)
- {
- ex.reason += string(": ") + strerror(errno);
- }
- fclose(stdioFileBZ2);
- throw ex;
- }
-
- fclose(stdioFileBZ2);
- file.close();
-
- //
- // Rename the temporary BZ2 file to the final BZ2 file. This is
- // done so that there can be no partial BZ2 files after an
- // abortive application termination.
- //
- ::remove(pathBZ2.c_str());
- if (::rename(pathBZ2Temp.c_str(), pathBZ2.c_str()) == -1)
- {
- FileAccessException ex;
- ex.reason = "cannot rename `" + pathBZ2Temp + "' to `" + pathBZ2 + "': " + strerror(errno);
- throw ex;
- }
-}
-
-void
-IcePatch::getRegular(const RegularPrx& regular, ProgressCB& progressCB)
-{
- string path = identityToPath(regular->ice_getIdentity());
- string pathBZ2 = path + ".bz2";
- Int totalBZ2 = regular->getBZ2Size();
-
- //
- // Get the BZ2 file.
- //
- progressCB.startDownload(totalBZ2);
-
- ofstream fileBZ2(pathBZ2.c_str(), ios::binary);
- if (!fileBZ2)
- {
- FileAccessException ex;
- ex.reason = "cannot open `" + pathBZ2 + "' for writing: " + strerror(errno);
- throw ex;
- }
-
- ByteSeq bytesBZ2;
- Int pos = 0;
- while(pos < totalBZ2)
- {
- static const Int num = 64 * 1024;
-
- bytesBZ2 = regular->getBZ2(pos, num);
- if (bytesBZ2.empty())
- {
- break;
- }
-
- pos += bytesBZ2.size();
-
- fileBZ2.write(&bytesBZ2[0], bytesBZ2.size());
- if (!fileBZ2)
- {
- FileAccessException ex;
- ex.reason = "cannot write `" + pathBZ2 + "': " + strerror(errno);
- throw ex;
- }
-
- if (static_cast<Int>(bytesBZ2.size()) < num)
- {
- break;
- }
-
- progressCB.updateDownload(totalBZ2, pos);
- }
-
- progressCB.finishedDownload(totalBZ2);
-
- fileBZ2.close();
-
- //
- // Read the BZ2 file in blocks and write the original file.
- //
- ofstream file(path.c_str(), ios::binary);
- if (!file)
- {
- FileAccessException ex;
- ex.reason = "cannot open `" + path + "' for writing: " + strerror(errno);
- throw ex;
- }
-
- FILE* stdioFileBZ2 = fopen(pathBZ2.c_str(), "rb");
- if (!stdioFileBZ2)
- {
- FileAccessException ex;
- ex.reason = "cannot open `" + pathBZ2 + "' for reading: " + strerror(errno);
- throw ex;
- }
-
- int bzError;
- BZFILE* bzFile = BZ2_bzReadOpen(&bzError, stdioFileBZ2, 0, 0, 0, 0);
- if (bzError != BZ_OK)
- {
- FileAccessException ex;
- ex.reason = "BZ2_bzReadOpen failed";
- if (bzError == BZ_IO_ERROR)
- {
- ex.reason += string(": ") + strerror(errno);
- }
- fclose(stdioFileBZ2);
- throw ex;
- }
-
- static const Int num = 64 * 1024;
- Byte bytes[num];
-
- progressCB.startUncompress(totalBZ2);
- int countBZ2 = 0;
-
- while (bzError != BZ_STREAM_END)
- {
- int sz = BZ2_bzRead(&bzError, bzFile, bytes, num);
- if (bzError != BZ_OK && bzError != BZ_STREAM_END)
- {
- FileAccessException ex;
- ex.reason = "BZ2_bzRead failed";
- if (bzError == BZ_IO_ERROR)
- {
- ex.reason += string(": ") + strerror(errno);
- }
- BZ2_bzReadClose(&bzError, bzFile);
- fclose(stdioFileBZ2);
- throw ex;
- }
-
- if (sz > 0)
- {
- countBZ2 += sz;
- progressCB.updateUncompress(totalBZ2, countBZ2);
-
- file.write(bytes, sz);
- if (!file)
- {
- FileAccessException ex;
- ex.reason = "cannot write `" + path + "': " + strerror(errno);
- BZ2_bzReadClose(&bzError, bzFile);
- fclose(stdioFileBZ2);
- throw ex;
- }
- }
- }
-
- progressCB.finishedUncompress(totalBZ2);
-
- BZ2_bzReadClose(&bzError, bzFile);
- if (bzError != BZ_OK)
- {
- FileAccessException ex;
- ex.reason = "BZ2_bzReadClose failed";
- if (bzError == BZ_IO_ERROR)
- {
- ex.reason += string(": ") + strerror(errno);
- }
- fclose(stdioFileBZ2);
- throw ex;
- }
-
- fclose(stdioFileBZ2);
- file.close();
-
- //
- // Remove the BZ2 file, it is not needed anymore.
- //
- if (::remove(pathBZ2.c_str()) == -1)
- {
- FileAccessException ex;
- ex.reason = "cannot remove file `" + pathBZ2 + "': " + strerror(errno);
- throw ex;
- }
-
- //
- // Create a MD5 file for the original file.
- //
- createMD5(path);
-}
+// **********************************************************************
+//
+// Copyright (c) 2002
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IcePatch/Util.h>
+#include <fstream>
+#include <sys/stat.h>
+#include <openssl/md5.h>
+#include <bzlib.h>
+
+#ifndef _WIN32
+# include <unistd.h>
+# include <dirent.h>
+#else
+# include <direct.h>
+# include <io.h>
+# define S_ISDIR(mode) ((mode) & _S_IFDIR)
+# define S_ISREG(mode) ((mode) & _S_IFREG)
+#endif
+
+using namespace std;
+using namespace Ice;
+using namespace IcePatch;
+
+string
+normalizePath(const string& path)
+{
+ string result = path;
+
+ string::size_type pos;
+
+ for (pos = 0; pos < result.size(); ++pos)
+ {
+ if (result[pos] == '\\')
+ {
+ result[pos] = '/';
+ }
+ }
+
+ 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);
+ }
+
+ if (result.substr(0, 2) == "./")
+ {
+ result.erase(0, 2);
+ }
+
+ return result;
+}
+
+string
+IcePatch::identityToPath(const Identity& ident)
+{
+ assert(ident.category == "IcePatch");
+ return normalizePath(ident.name);
+}
+
+Identity
+IcePatch::pathToIdentity(const string& path)
+{
+ Identity ident;
+ ident.category = "IcePatch";
+ ident.name = normalizePath(path);
+ return ident;
+}
+
+string
+IcePatch::getSuffix(const string& path)
+{
+ string::size_type pos = path.rfind('.');
+ if (pos == string::npos)
+ {
+ return string();
+ }
+ else
+ {
+ return path.substr(pos + 1);
+ }
+}
+
+bool
+IcePatch::ignoreSuffix(const string& path)
+{
+ string suffix = getSuffix(path);
+ return suffix == "md5" || suffix == "md5temp" || suffix == "bz2" || suffix == "bz2temp";
+}
+
+string
+IcePatch::removeSuffix(const string& path)
+{
+ string::size_type pos = path.rfind('.');
+ if (pos == string::npos)
+ {
+ return path;
+ }
+ else
+ {
+ return path.substr(0, pos);
+ }
+}
+
+FileInfo
+IcePatch::getFileInfo(const string& path, bool exceptionIfNotExist)
+{
+ struct stat buf;
+ if (::stat(path.c_str(), &buf) == -1)
+ {
+ if (!exceptionIfNotExist && errno == ENOENT)
+ {
+ FileInfo result;
+ result.size = 0;
+ result.time = 0;
+ result.type = FileTypeNotExist;
+ return result;
+ }
+ else
+ {
+ FileAccessException ex;
+ ex.reason = "cannot stat `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+ }
+
+ FileInfo result;
+ result.size = buf.st_size;
+ result.time = buf.st_mtime;
+
+ if (S_ISDIR(buf.st_mode))
+ {
+ result.type = FileTypeDirectory;
+ }
+ else if (S_ISREG(buf.st_mode))
+ {
+ result.type = FileTypeRegular;
+ }
+ else
+ {
+ result.type = FileTypeUnknown;
+ }
+
+ return result;
+}
+
+void
+IcePatch::removeRecursive(const string& path)
+{
+ if (getFileInfo(path, true).type == FileTypeDirectory)
+ {
+ StringSeq paths = readDirectory(path);
+ for (StringSeq::const_iterator p = paths.begin(); p != paths.end(); ++p)
+ {
+ removeRecursive(*p);
+ }
+ }
+
+ if (::remove(path.c_str()) == -1)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot remove file `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+}
+
+void
+IcePatch::changeDirectory(const string& path)
+{
+#ifdef _WIN32
+ if (_chdir(path.c_str()) == -1)
+#else
+ if (chdir(path.c_str()) == -1)
+#endif
+ {
+ FileAccessException ex;
+ ex.reason = "cannot change to directory `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+}
+
+StringSeq
+IcePatch::readDirectory(const string& path)
+{
+#ifdef _WIN32
+
+ struct _finddata_t data;
+ long h = _findfirst((path + "/*").c_str(), &data);
+ if (h == -1)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot read directory `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+
+ StringSeq result;
+
+ while (true)
+ {
+ string name = data.name;
+
+ if (name != ".." && name != ".")
+ {
+ result.push_back(normalizePath(path + '/' + name));
+ }
+
+ if (_findnext(h, &data) == -1)
+ {
+ if (errno == ENOENT)
+ {
+ break;
+ }
+
+ FileAccessException ex;
+ ex.reason = "cannot read directory `" + path + "': " + strerror(errno);
+ _findclose(h);
+ throw ex;
+ }
+ }
+
+ _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)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot read directory `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+
+ StringSeq result;
+ result.reserve(n - 2);
+
+ for (int i = 0; i < n; ++i)
+ {
+ string name = namelist[i]->d_name;
+
+ free(namelist[i]);
+
+ if (name != ".." && name != ".")
+ {
+ result.push_back(normalizePath(path + '/' + name));
+ }
+ }
+
+ free(namelist);
+ return result;
+
+#endif
+}
+
+void
+IcePatch::createDirectory(const string& path)
+{
+#ifdef _WIN32
+ if (::_mkdir(path.c_str()) == -1)
+#else
+ if (::mkdir(path.c_str(), 00777) == -1)
+#endif
+ {
+ FileAccessException ex;
+ ex.reason = "cannot create directory `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+}
+
+ByteSeq
+IcePatch::getMD5(const string& path)
+{
+ string pathMD5 = path + ".md5";
+ ifstream fileMD5(pathMD5.c_str(), ios::binary);
+ if (!fileMD5)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + pathMD5 + "' for reading: " + strerror(errno);
+ throw ex;
+ }
+ ByteSeq bytesMD5;
+ bytesMD5.resize(16);
+ fileMD5.read(&bytesMD5[0], 16);
+ if (!fileMD5)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot read `" + pathMD5 + "': " + strerror(errno);
+ throw ex;
+ }
+ if (fileMD5.gcount() < 16)
+ {
+ FileAccessException ex;
+ ex.reason = "could not read 16 bytes from `" + pathMD5 + "'";
+ throw ex;
+ }
+ fileMD5.close();
+ return bytesMD5;
+}
+
+void
+IcePatch::createMD5(const string& path)
+{
+ FileInfo info = getFileInfo(path, true);
+ assert(info.type == FileTypeRegular);
+
+ //
+ // Read the original file.
+ //
+ ifstream file(path.c_str(), ios::binary);
+ if (!file)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + path + "' for reading: " + strerror(errno);
+ throw ex;
+ }
+ ByteSeq bytes;
+ bytes.resize(info.size);
+ file.read(&bytes[0], bytes.size());
+ if (!file)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot read `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+ if (file.gcount() < static_cast<int>(bytes.size()))
+ {
+ FileAccessException ex;
+ ex.reason = "could not read all bytes from `" + path + "'";
+ throw ex;
+ }
+ file.close();
+
+ //
+ // Create the MD5 hash value.
+ //
+ ByteSeq bytesMD5;
+ bytesMD5.resize(16);
+ MD5(reinterpret_cast<unsigned char*>(&bytes[0]), bytes.size(), reinterpret_cast<unsigned char*>(&bytesMD5[0]));
+
+ //
+ // Save the MD5 hash value to a temporary MD5 file.
+ //
+ string pathMD5 = path + ".md5";
+ string pathMD5Temp = path + ".md5temp";
+ ofstream fileMD5(pathMD5Temp.c_str(), ios::binary);
+ if (!fileMD5)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + pathMD5Temp + "' for writing: " + strerror(errno);
+ throw ex;
+ }
+ fileMD5.write(&bytesMD5[0], 16);
+ if (!fileMD5)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot write `" + pathMD5Temp + "': " + strerror(errno);
+ throw ex;
+ }
+ fileMD5.close();
+
+ //
+ // Rename the temporary MD5 file to the final MD5 file. This is
+ // done so that there can be no partial MD5 files after an
+ // abortive application termination.
+ //
+ ::remove(pathMD5.c_str());
+ if (::rename(pathMD5Temp.c_str(), pathMD5.c_str()) == -1)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot rename `" + pathMD5Temp + "' to `" + pathMD5 + "': " + strerror(errno);
+ throw ex;
+ }
+}
+
+ByteSeq
+IcePatch::getBZ2(const string& path, Int pos, Int num)
+{
+ string pathBZ2 = path + ".bz2";
+ ifstream fileBZ2(pathBZ2.c_str(), ios::binary);
+ if (!fileBZ2)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + pathBZ2 + "' for reading: " + strerror(errno);
+ throw ex;
+ }
+ fileBZ2.seekg(pos);
+ if (!fileBZ2)
+ {
+ FileAccessException ex;
+ ostringstream out;
+ out << "cannot seek position " << pos << " in file `" << path << "':" << strerror(errno);
+ ex.reason = out.str();
+ throw ex;
+ }
+ ByteSeq bytesBZ2;
+ bytesBZ2.resize(num);
+ fileBZ2.read(&bytesBZ2[0], bytesBZ2.size());
+ if (!fileBZ2 && !fileBZ2.eof())
+ {
+ FileAccessException ex;
+ ex.reason = "cannot read `" + pathBZ2 + "': " + strerror(errno);
+ throw ex;
+ }
+ bytesBZ2.resize(fileBZ2.gcount());
+ fileBZ2.close();
+ return bytesBZ2;
+}
+
+void
+IcePatch::createBZ2(const string& path)
+{
+ FileInfo info = getFileInfo(path, true);
+ assert(info.type == FileTypeRegular);
+
+ //
+ // Read the original file in blocks and write a temporary BZ2
+ // file.
+ //
+ ifstream file(path.c_str(), ios::binary);
+ if (!file)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + path + "' for reading: " + strerror(errno);
+ throw ex;
+ }
+
+ string pathBZ2 = path + ".bz2";
+ string pathBZ2Temp = path + ".bz2temp";
+ FILE* stdioFileBZ2 = fopen(pathBZ2Temp.c_str(), "wb");
+ if (!stdioFileBZ2)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + pathBZ2Temp + "' for writing: " + strerror(errno);
+ throw ex;
+ }
+
+ int bzError;
+ BZFILE* bzFile = BZ2_bzWriteOpen(&bzError, stdioFileBZ2, 5, 0, 0);
+ if (bzError != BZ_OK)
+ {
+ FileAccessException ex;
+ ex.reason = "BZ2_bzWriteOpen failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
+ fclose(stdioFileBZ2);
+ throw ex;
+ }
+
+ static const Int num = 64 * 1024;
+ Byte bytes[num];
+
+ while (!file.eof())
+ {
+ file.read(bytes, num);
+ if (!file && !file.eof())
+ {
+ FileAccessException ex;
+ ex.reason = "cannot read `" + path + "': " + strerror(errno);
+ BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
+ fclose(stdioFileBZ2);
+ throw ex;
+ }
+
+ if (file.gcount() > 0)
+ {
+ BZ2_bzWrite(&bzError, bzFile, bytes, file.gcount());
+ if (bzError != BZ_OK)
+ {
+ FileAccessException ex;
+ ex.reason = "BZ2_bzWrite failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
+ BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
+ fclose(stdioFileBZ2);
+ throw ex;
+ }
+ }
+ }
+
+ BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0);
+ if (bzError != BZ_OK)
+ {
+ FileAccessException ex;
+ ex.reason = "BZ2_bzWriteClose failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
+ fclose(stdioFileBZ2);
+ throw ex;
+ }
+
+ fclose(stdioFileBZ2);
+ file.close();
+
+ //
+ // Rename the temporary BZ2 file to the final BZ2 file. This is
+ // done so that there can be no partial BZ2 files after an
+ // abortive application termination.
+ //
+ ::remove(pathBZ2.c_str());
+ if (::rename(pathBZ2Temp.c_str(), pathBZ2.c_str()) == -1)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot rename `" + pathBZ2Temp + "' to `" + pathBZ2 + "': " + strerror(errno);
+ throw ex;
+ }
+}
+
+void
+IcePatch::getRegular(const RegularPrx& regular, ProgressCB& progressCB)
+{
+ string path = identityToPath(regular->ice_getIdentity());
+ string pathBZ2 = path + ".bz2";
+ Int totalBZ2 = regular->getBZ2Size();
+
+ //
+ // Get the BZ2 file.
+ //
+ progressCB.startDownload(totalBZ2);
+
+ ofstream fileBZ2(pathBZ2.c_str(), ios::binary);
+ if (!fileBZ2)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + pathBZ2 + "' for writing: " + strerror(errno);
+ throw ex;
+ }
+
+ ByteSeq bytesBZ2;
+ Int pos = 0;
+ while(pos < totalBZ2)
+ {
+ static const Int num = 64 * 1024;
+
+ bytesBZ2 = regular->getBZ2(pos, num);
+ if (bytesBZ2.empty())
+ {
+ break;
+ }
+
+ pos += bytesBZ2.size();
+
+ fileBZ2.write(&bytesBZ2[0], bytesBZ2.size());
+ if (!fileBZ2)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot write `" + pathBZ2 + "': " + strerror(errno);
+ throw ex;
+ }
+
+ if (static_cast<Int>(bytesBZ2.size()) < num)
+ {
+ break;
+ }
+
+ progressCB.updateDownload(totalBZ2, pos);
+ }
+
+ progressCB.finishedDownload(totalBZ2);
+
+ fileBZ2.close();
+
+ //
+ // Read the BZ2 file in blocks and write the original file.
+ //
+ ofstream file(path.c_str(), ios::binary);
+ if (!file)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + path + "' for writing: " + strerror(errno);
+ throw ex;
+ }
+
+ FILE* stdioFileBZ2 = fopen(pathBZ2.c_str(), "rb");
+ if (!stdioFileBZ2)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + pathBZ2 + "' for reading: " + strerror(errno);
+ throw ex;
+ }
+
+ int bzError;
+ BZFILE* bzFile = BZ2_bzReadOpen(&bzError, stdioFileBZ2, 0, 0, 0, 0);
+ if (bzError != BZ_OK)
+ {
+ FileAccessException ex;
+ ex.reason = "BZ2_bzReadOpen failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
+ fclose(stdioFileBZ2);
+ throw ex;
+ }
+
+ static const Int num = 64 * 1024;
+ Byte bytes[num];
+
+ progressCB.startUncompress(totalBZ2);
+ int countBZ2 = 0;
+
+ while (bzError != BZ_STREAM_END)
+ {
+ int sz = BZ2_bzRead(&bzError, bzFile, bytes, num);
+ if (bzError != BZ_OK && bzError != BZ_STREAM_END)
+ {
+ FileAccessException ex;
+ ex.reason = "BZ2_bzRead failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
+ BZ2_bzReadClose(&bzError, bzFile);
+ fclose(stdioFileBZ2);
+ throw ex;
+ }
+
+ if (sz > 0)
+ {
+ countBZ2 += sz;
+ progressCB.updateUncompress(totalBZ2, countBZ2);
+
+ file.write(bytes, sz);
+ if (!file)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot write `" + path + "': " + strerror(errno);
+ BZ2_bzReadClose(&bzError, bzFile);
+ fclose(stdioFileBZ2);
+ throw ex;
+ }
+ }
+ }
+
+ progressCB.finishedUncompress(totalBZ2);
+
+ BZ2_bzReadClose(&bzError, bzFile);
+ if (bzError != BZ_OK)
+ {
+ FileAccessException ex;
+ ex.reason = "BZ2_bzReadClose failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
+ fclose(stdioFileBZ2);
+ throw ex;
+ }
+
+ fclose(stdioFileBZ2);
+ file.close();
+
+ //
+ // Remove the BZ2 file, it is not needed anymore.
+ //
+ if (::remove(pathBZ2.c_str()) == -1)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot remove file `" + pathBZ2 + "': " + strerror(errno);
+ throw ex;
+ }
+
+ //
+ // Create a MD5 file for the original file.
+ //
+ createMD5(path);
+}