summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/IcePatch/Util.h18
-rw-r--r--cpp/slice/IcePatch/Node.ice4
-rw-r--r--cpp/src/IcePatch/.depend2
-rw-r--r--cpp/src/IcePatch/Client.cpp34
-rw-r--r--cpp/src/IcePatch/NodeI.cpp11
-rw-r--r--cpp/src/IcePatch/NodeI.h1
-rw-r--r--cpp/src/IcePatch/Server.cpp15
-rw-r--r--cpp/src/IcePatch/Util.cpp290
8 files changed, 272 insertions, 103 deletions
diff --git a/cpp/include/IcePatch/Util.h b/cpp/include/IcePatch/Util.h
index 6c080ecc65e..159e79055b4 100644
--- a/cpp/include/IcePatch/Util.h
+++ b/cpp/include/IcePatch/Util.h
@@ -17,6 +17,8 @@
namespace IcePatch
{
+extern const std::string tmpName;
+
std::string identityToPath(const Ice::Identity&);
Ice::Identity pathToIdentity(const std::string&);
@@ -36,14 +38,26 @@ void removeRecursive(const std::string&);
void createDirectory(const std::string&);
Ice::ByteSeq getMD5(const std::string&);
-std::string MD5ToString(const Ice::ByteSeq&);
+void createMD5(const std::string&);
+void createMD5Recursive(const std::string&);
void writeBZ2(const std::string&, const Ice::ByteSeq&);
Ice::ByteSeq readBZ2(const std::string&);
+Ice::Int getSizeBZ2(const std::string&);
Ice::ByteSeq getBytesBZ2(const std::string&, Ice::Int, Ice::Int);
+void createBZ2(const std::string&);
+void createBZ2Recursive(const std::string&);
+
+class ProgressCB
+{
+public:
-void getFile(const IcePatch::FilePrx&);
+ virtual void start(Ice::Int) = 0;
+ virtual void update(Ice::Int, Ice::Int) = 0;
+ virtual void finished(Ice::Int) = 0;
+};
+void getFile(const IcePatch::FilePrx&, ProgressCB&);
}
diff --git a/cpp/slice/IcePatch/Node.ice b/cpp/slice/IcePatch/Node.ice
index 297cd676cf0..289cfc1acee 100644
--- a/cpp/slice/IcePatch/Node.ice
+++ b/cpp/slice/IcePatch/Node.ice
@@ -46,6 +46,9 @@ class DirectoryDesc extends NodeDesc
interface File extends Node
{
+ int getSizeBZ2()
+ throws NodeAccessException;
+
Ice::ByteSeq getBytesBZ2(int pos, int num)
throws NodeAccessException;
};
@@ -53,6 +56,7 @@ interface File extends Node
class FileDesc extends NodeDesc
{
File* file;
+ int size;
Ice::ByteSeq md5;
};
diff --git a/cpp/src/IcePatch/.depend b/cpp/src/IcePatch/.depend
index cd2bae90cf9..75260b212d2 100644
--- a/cpp/src/IcePatch/.depend
+++ b/cpp/src/IcePatch/.depend
@@ -2,7 +2,7 @@ Node.o: Node.cpp ../../include/Ice/Stream.h ../../include/Ice/ProxyF.h ../../inc
NodeDescFactory.o: NodeDescFactory.cpp ../../include/IcePatch/NodeDescFactory.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/Properties.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Communicator.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/SystemF.h ../../include/Ice/SslExtensionF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/IcePatch/Node.h
Util.o: Util.cpp ../../include/IcePatch/Util.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/Properties.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Communicator.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/SystemF.h ../../include/Ice/SslExtensionF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/IcePatch/Node.h
Client.o: Client.cpp ../../include/Ice/Application.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/Properties.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Communicator.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/SystemF.h ../../include/Ice/SslExtensionF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/IcePatch/NodeDescFactory.h ../../include/IcePatch/Node.h ../../include/IcePatch/Util.h
-Server.o: Server.cpp ../../include/Ice/Application.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/Properties.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Communicator.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/SystemF.h ../../include/Ice/SslExtensionF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../IcePatch/NodeLocator.h ../IcePatch/NodeI.h ../../include/IcePatch/Node.h
+Server.o: Server.cpp ../../include/Ice/Application.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/Properties.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Communicator.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/SystemF.h ../../include/Ice/SslExtensionF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../IcePatch/NodeLocator.h ../IcePatch/NodeI.h ../../include/IcePatch/Node.h ../../include/IcePatch/Util.h
NodeI.o: NodeI.cpp ../IcePatch/NodeI.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/Properties.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Communicator.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/SystemF.h ../../include/Ice/SslExtensionF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/IcePatch/Node.h ../../include/IcePatch/Util.h
NodeLocator.o: NodeLocator.cpp ../IcePatch/NodeLocator.h ../IcePatch/NodeI.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ProxyHandle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/StreamF.h ../../include/Ice/PropertiesF.h ../../include/Ice/InstanceF.h ../../include/Ice/Properties.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/Communicator.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionF.h ../../include/Ice/EndpointF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/Current.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/SystemF.h ../../include/Ice/SslExtensionF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocator.h ../../include/Ice/IdentityUtil.h ../../include/IcePatch/Node.h ../../include/IcePatch/Util.h
blocksort.o: blocksort.c bzlib_private.h bzlib.h
diff --git a/cpp/src/IcePatch/Client.cpp b/cpp/src/IcePatch/Client.cpp
index f4541e52a6c..ec2a12f6b2d 100644
--- a/cpp/src/IcePatch/Client.cpp
+++ b/cpp/src/IcePatch/Client.cpp
@@ -11,6 +11,7 @@
#include <Ice/Application.h>
#include <IcePatch/NodeDescFactory.h>
#include <IcePatch/Util.h>
+#include <iomanip>
using namespace std;
using namespace Ice;
@@ -116,13 +117,34 @@ IcePatch::Client::run(int argc, char* argv[])
}
catch (const NodeAccessException& ex)
{
- cerr << ex << ":\n" << ex.reason << endl;
+ cerr << appName() << ": " << ex << ":\n" << ex.reason << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
+class MyProgressCB : public ProgressCB
+{
+public:
+
+ virtual void start(Int)
+ {
+ cout << " 0% " << flush;
+ }
+
+ virtual void update(Int total, Int pos)
+ {
+ Ice::Int percent = pos * 100 / total;
+ cout << "\b\b\b\b\b" << setw(3) << percent << "% " << flush;
+ }
+
+ virtual void finished(Int total)
+ {
+ cout << "\b\b\b\b\b" << "100% " << flush;
+ }
+};
+
void
IcePatch::Client::printNodeDescSeq(const NodeDescSeq& nodeDescSeq, const string& indent)
{
@@ -206,13 +228,15 @@ IcePatch::Client::printNodeDescSeq(const NodeDescSeq& nodeDescSeq, const string&
assert(fileDesc);
cout << indent << "+-" << pathToName(path) << "... " << flush;
+ MyProgressCB progressCB;
+
FileInfo info = getFileInfo(path);
switch (info)
{
case FileInfoNotExist:
{
cout << "getting file... " << flush;
- getFile(fileDesc->file);
+ getFile(fileDesc->file, progressCB);
break;
}
@@ -221,7 +245,7 @@ IcePatch::Client::printNodeDescSeq(const NodeDescSeq& nodeDescSeq, const string&
cout << "removing directory... " << flush;
removeRecursive(path);
cout << "getting file... " << flush;
- getFile(fileDesc->file);
+ getFile(fileDesc->file, progressCB);
break;
}
@@ -233,7 +257,7 @@ IcePatch::Client::printNodeDescSeq(const NodeDescSeq& nodeDescSeq, const string&
cout << "removing file... " << flush;
removeRecursive(path);
cout << "getting file... " << flush;
- getFile(fileDesc->file);
+ getFile(fileDesc->file, progressCB);
}
break;
}
@@ -243,7 +267,7 @@ IcePatch::Client::printNodeDescSeq(const NodeDescSeq& nodeDescSeq, const string&
cout << "removing unknown file... " << flush;
removeRecursive(path);
cout << "getting file... " << flush;
- getFile(fileDesc->file);
+ getFile(fileDesc->file, progressCB);
break;
}
}
diff --git a/cpp/src/IcePatch/NodeI.cpp b/cpp/src/IcePatch/NodeI.cpp
index abbc06b0cd4..02cea3d9e93 100644
--- a/cpp/src/IcePatch/NodeI.cpp
+++ b/cpp/src/IcePatch/NodeI.cpp
@@ -44,6 +44,11 @@ IcePatch::DirectoryI::getContents(const Ice::Current& current)
StringSeq::const_iterator p;
for (p = paths.begin(); p != paths.end(); ++p)
{
+ if (pathToName(*p) == tmpName)
+ {
+ continue;
+ }
+
string suffix = getSuffix(*p);
if (suffix == "md5" || suffix == "bz2")
{
@@ -81,6 +86,12 @@ IcePatch::FileI::describe(const Ice::Current& current)
return desc;
}
+Int
+IcePatch::FileI::getSizeBZ2(const Ice::Current& current)
+{
+ return IcePatch::getSizeBZ2(identityToPath(current.identity));
+}
+
ByteSeq
IcePatch::FileI::getBytesBZ2(Ice::Int pos, Ice::Int num, const Ice::Current& current)
{
diff --git a/cpp/src/IcePatch/NodeI.h b/cpp/src/IcePatch/NodeI.h
index 93e7db2d6be..ba9167b940b 100644
--- a/cpp/src/IcePatch/NodeI.h
+++ b/cpp/src/IcePatch/NodeI.h
@@ -47,6 +47,7 @@ public:
FileI(const Ice::ObjectAdapterPtr&);
virtual NodeDescPtr describe(const Ice::Current&);
+ virtual Ice::Int getSizeBZ2(const Ice::Current&);
virtual Ice::ByteSeq getBytesBZ2(Ice::Int, Ice::Int, const Ice::Current&);
};
diff --git a/cpp/src/IcePatch/Server.cpp b/cpp/src/IcePatch/Server.cpp
index 10db1b9db92..371e72a9b0f 100644
--- a/cpp/src/IcePatch/Server.cpp
+++ b/cpp/src/IcePatch/Server.cpp
@@ -10,6 +10,7 @@
#include <Ice/Application.h>
#include <IcePatch/NodeLocator.h>
+#include <IcePatch/Util.h>
using namespace std;
using namespace Ice;
@@ -90,6 +91,20 @@ IcePatch::Server::run(int argc, char* argv[])
}
//
+ // Create MD5 and BZ2 files.
+ //
+ try
+ {
+ createMD5Recursive(".");
+ createBZ2Recursive(".");
+ }
+ catch (const NodeAccessException& ex)
+ {
+ cerr << appName() << ": " << ex << ":\n" << ex.reason << endl;
+ return EXIT_FAILURE;
+ }
+
+ //
// Create and initialize the object adapter and the node locator.
//
ObjectAdapterPtr adapter = communicator()->createObjectAdapterFromProperty("IcePatch", endpointsProperty);
diff --git a/cpp/src/IcePatch/Util.cpp b/cpp/src/IcePatch/Util.cpp
index 957133e139b..63da8e356ee 100644
--- a/cpp/src/IcePatch/Util.cpp
+++ b/cpp/src/IcePatch/Util.cpp
@@ -22,6 +22,8 @@ using namespace std;
using namespace Ice;
using namespace IcePatch;
+const string IcePatch::tmpName = ".icepatchtmp";
+
static string
normalizePath(const string& path)
{
@@ -193,6 +195,46 @@ IcePatch::createDirectory(const string& path)
ByteSeq
IcePatch::getMD5(const string& path)
{
+ string pathMD5 = path + ".md5";
+ ifstream fileMD5(pathMD5.c_str());
+ if (!fileMD5)
+ {
+ NodeAccessException ex;
+ ex.reason = "cannot open `" + pathMD5 + "' for reading:" + strerror(errno);
+ throw ex;
+ }
+ ByteSeq bytesMD5;
+ bytesMD5.resize(16);
+ fileMD5.read(&bytesMD5[0], 16);
+ if (!fileMD5)
+ {
+ NodeAccessException ex;
+ ex.reason = "cannot read `" + pathMD5 + "':" + strerror(errno);
+ throw ex;
+ }
+ if (fileMD5.gcount() < 16)
+ {
+ NodeAccessException ex;
+ ex.reason = "could not read 16 bytes from `" + pathMD5 + "'";
+ throw ex;
+ }
+ return bytesMD5;
+}
+
+void
+IcePatch::createMD5(const string& path)
+{
+ if (pathToName(path) == tmpName)
+ {
+ return;
+ }
+
+ string suffix = getSuffix(path);
+ if (suffix == "md5" || suffix == "bz2")
+ {
+ return;
+ }
+
//
// Stat the file to get a MD5 hash value for.
//
@@ -219,12 +261,12 @@ IcePatch::getMD5(const string& path)
//
struct stat bufMD5;
string pathMD5 = path + ".md5";
- bool createMD5 = false;
+ bool makeMD5 = false;
if (::stat(pathMD5.c_str(), &bufMD5) == -1)
{
if (errno == ENOENT)
{
- createMD5 = true;
+ makeMD5 = true;
}
else
{
@@ -238,27 +280,24 @@ IcePatch::getMD5(const string& path)
if (!S_ISREG(bufMD5.st_mode))
{
NodeAccessException ex;
- ex.reason = "`" + path + "' is not a regular file";
+ ex.reason = "`" + pathMD5 + "' is not a regular file";
throw ex;
}
if (bufMD5.st_size != 16)
{
NodeAccessException ex;
- ex.reason = "`" + path + "' isn't 16 bytes in size";
+ ex.reason = "`" + pathMD5 + "' isn't 16 bytes in size";
throw ex;
}
if (bufMD5.st_mtime <= buf.st_mtime)
{
- createMD5 = true;
+ makeMD5 = true;
}
}
- ByteSeq bytesMD5;
- bytesMD5.resize(16);
-
- if (createMD5)
+ if (makeMD5)
{
//
// Read the original file.
@@ -290,79 +329,61 @@ IcePatch::getMD5(const string& path)
//
// 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 the MD5 file.
//
- ofstream fileMD5(pathMD5.c_str());
+ ofstream fileMD5(tmpName.c_str());
if (!fileMD5)
{
NodeAccessException ex;
- ex.reason = "cannot open `" + pathMD5 + "' for writing:" + strerror(errno);
+ ex.reason = "cannot open `" + tmpName + "' for writing:" + strerror(errno);
throw ex;
}
fileMD5.write(&bytesMD5[0], 16);
if (!fileMD5)
{
NodeAccessException ex;
- ex.reason = "cannot write `" + pathMD5 + "':" + strerror(errno);
+ ex.reason = "cannot write `" + tmpName + "':" + strerror(errno);
throw ex;
}
fileMD5.close();
- }
- else
- {
+
//
- // Read the MD5 hash value from the MD5 file.
+ // Rename the temporary MD5 file to the "real" MD5 file. This
+ // is done so that there can be no partial MD5 files after an
+ // abortive application termination.
//
- ifstream fileMD5(pathMD5.c_str());
- if (!fileMD5)
- {
- NodeAccessException ex;
- ex.reason = "cannot open `" + pathMD5 + "' for reading:" + strerror(errno);
- throw ex;
- }
- fileMD5.read(&bytesMD5[0], 16);
- if (!fileMD5)
- {
- NodeAccessException ex;
- ex.reason = "cannot read `" + pathMD5 + "':" + strerror(errno);
- throw ex;
- }
- if (fileMD5.gcount() < 16)
+ if (rename(tmpName.c_str(), pathMD5.c_str()) == -1)
{
NodeAccessException ex;
- ex.reason = "could not read 16 bytes from `" + pathMD5 + "'";
+ ex.reason = "cannot rename `" + tmpName + "' to `" + pathMD5 + "':" + strerror(errno);
throw ex;
}
- fileMD5.close();
}
-
- return bytesMD5;
}
-string
-IcePatch::MD5ToString(const ByteSeq& bytesMD5)
+void
+IcePatch::createMD5Recursive(const string& path)
{
- if (bytesMD5.size() != 16)
- {
- return "illegal MD5 hash code";
- }
-
- ostringstream out;
+ FileInfo info = getFileInfo(path);
- for (int i = 0; i < 16; ++i)
+ if (info == FileInfoDirectory)
{
- int b = static_cast<int>(bytesMD5[i]);
- if (b < 0)
+ StringSeq paths = readDirectory(path);
+ StringSeq::const_iterator p;
+ for (p = paths.begin(); p != paths.end(); ++p)
{
- b += 256;
+ createMD5Recursive(*p);
}
- out << hex << b;
}
-
- return out.str();
+ else if (info == FileInfoRegular)
+ {
+ createMD5(path);
+ }
}
void
@@ -375,6 +396,12 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes)
ex.reason = "cannot open `" + pathBZ2 + "' for writing:" + strerror(errno);
throw ex;
}
+
+ if (bytes.empty())
+ {
+ fclose(file);
+ return;
+ }
try
{
@@ -384,6 +411,10 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes)
{
NodeAccessException ex;
ex.reason = "BZ2_bzWriteOpen failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
throw ex;
}
@@ -394,6 +425,10 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes)
{
NodeAccessException ex;
ex.reason = "BZ2_bzWrite failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
throw ex;
}
@@ -402,6 +437,10 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes)
{
NodeAccessException ex;
ex.reason = "BZ2_bzWriteClose failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
throw ex;
}
}
@@ -412,6 +451,10 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes)
{
NodeAccessException ex;
ex.reason = "BZ2_bzWriteClose failed";
+ if (bzError == BZ_IO_ERROR)
+ {
+ ex.reason += string(": ") + strerror(errno);
+ }
throw ex;
}
throw;
@@ -426,9 +469,67 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes)
}
}
+Int
+IcePatch::getSizeBZ2(const string& path)
+{
+ struct stat bufBZ2;
+ string pathBZ2 = path + ".bz2";
+ if (::stat(pathBZ2.c_str(), &bufBZ2) == -1)
+ {
+ NodeAccessException ex;
+ ex.reason = "cannot stat `" + path + "':" + strerror(errno);
+ throw ex;
+ }
+ return bufBZ2.st_size;
+}
+
ByteSeq
IcePatch::getBytesBZ2(const string& path, Int pos, Int num)
{
+ string pathBZ2 = path + ".bz2";
+ ifstream fileBZ2(pathBZ2.c_str());
+ if (!fileBZ2)
+ {
+ NodeAccessException ex;
+ ex.reason = "cannot open `" + pathBZ2 + "' for reading:" + strerror(errno);
+ throw ex;
+ }
+ fileBZ2.seekg(pos);
+ if (!fileBZ2)
+ {
+ NodeAccessException 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())
+ {
+ NodeAccessException ex;
+ ex.reason = "cannot read `" + pathBZ2 + "':" + strerror(errno);
+ throw ex;
+ }
+ bytesBZ2.resize(fileBZ2.gcount());
+ return bytesBZ2;
+}
+
+void
+IcePatch::createBZ2(const string& path)
+{
+ if (pathToName(path) == tmpName)
+ {
+ return;
+ }
+
+ string suffix = getSuffix(path);
+ if (suffix == "md5" || suffix == "bz2")
+ {
+ return;
+ }
+
//
// Stat the file to get a BZ2 file for.
//
@@ -455,12 +556,12 @@ IcePatch::getBytesBZ2(const string& path, Int pos, Int num)
//
struct stat bufBZ2;
string pathBZ2 = path + ".bz2";
- bool createBZ2 = false;
+ bool makeBZ2 = false;
if (::stat(pathBZ2.c_str(), &bufBZ2) == -1)
{
if (errno == ENOENT)
{
- createBZ2 = true;
+ makeBZ2 = true;
}
else
{
@@ -474,17 +575,17 @@ IcePatch::getBytesBZ2(const string& path, Int pos, Int num)
if (!S_ISREG(bufBZ2.st_mode))
{
NodeAccessException ex;
- ex.reason = "`" + path + "' is not a regular file";
+ ex.reason = "`" + pathBZ2 + "' is not a regular file";
throw ex;
}
if (bufBZ2.st_mtime <= buf.st_mtime)
{
- createBZ2 = true;
+ makeBZ2 = true;
}
}
- if (createBZ2)
+ if (makeBZ2)
{
//
// Read the original file.
@@ -514,63 +615,52 @@ IcePatch::getBytesBZ2(const string& path, Int pos, Int num)
file.close();
//
- // Create the BZ2 file.
+ // Write the BZ2 file.
//
- writeBZ2(pathBZ2, bytes);
+ writeBZ2(tmpName, bytes);
-/*
//
- // Stat the BZ2 file. This time, the BZ2 file must exist,
- // otherwise it's an error.
+ // Rename the temporary BZ2 file to the "real" BZ2 file. This
+ // is done so that there can be no partial BZ2 files after an
+ // abortive application termination.
//
- if (::stat(pathBZ2.c_str(), &bufBZ2) == -1)
+ if (rename(tmpName.c_str(), pathBZ2.c_str()) == -1)
{
NodeAccessException ex;
- ex.reason = "cannot stat `" + path + "':" + strerror(errno);
+ ex.reason = "cannot rename `" + tmpName + "' to `" + pathBZ2 + "':" + strerror(errno);
throw ex;
}
-*/
}
+}
- //
- // Read the BZ2 file.
- //
- ifstream fileBZ2(pathBZ2.c_str());
- if (!fileBZ2)
- {
- NodeAccessException ex;
- ex.reason = "cannot open `" + pathBZ2 + "' for reading:" + strerror(errno);
- throw ex;
- }
- fileBZ2.seekg(pos);
- if (!fileBZ2)
+void
+IcePatch::createBZ2Recursive(const string& path)
+{
+ FileInfo info = getFileInfo(path);
+
+ if (info == FileInfoDirectory)
{
- NodeAccessException ex;
- ostringstream out;
- out << "cannot seek position " << pos << " in file `" << path << "':" << strerror(errno);
- ex.reason = out.str();
- throw ex;
+ StringSeq paths = readDirectory(path);
+ StringSeq::const_iterator p;
+ for (p = paths.begin(); p != paths.end(); ++p)
+ {
+ createBZ2Recursive(*p);
+ }
}
- ByteSeq bytesBZ2;
- bytesBZ2.resize(num);
- fileBZ2.read(&bytesBZ2[0], bytesBZ2.size());
- if (!fileBZ2 && !fileBZ2.eof())
+ else if (info == FileInfoRegular)
{
- NodeAccessException ex;
- ex.reason = "cannot read `" + pathBZ2 + "':" + strerror(errno);
- throw ex;
+ createBZ2(path);
}
- bytesBZ2.resize(fileBZ2.gcount());
- fileBZ2.close();
-
- return bytesBZ2;
}
void
-IcePatch::getFile(const FilePrx& file)
+IcePatch::getFile(const FilePrx& file, ProgressCB& progressCB)
{
string path = identityToPath(file->ice_getIdentity());
+ Int totalBZ2 = file->getSizeBZ2();
+ progressCB.start(totalBZ2);
+
string pathBZ2 = path + ".bz2";
ofstream fileBZ2(pathBZ2.c_str());
if (!fileBZ2)
@@ -581,9 +671,11 @@ IcePatch::getFile(const FilePrx& file)
}
ByteSeq bytesBZ2;
Int pos = 0;
- while(true)
+ while(pos < totalBZ2)
{
- bytesBZ2 = file->getBytesBZ2(pos, 256 * 1024);
+ static const Int num = 64 * 1024;
+
+ bytesBZ2 = file->getBytesBZ2(pos, num);
if (bytesBZ2.empty())
{
break;
@@ -598,6 +690,14 @@ IcePatch::getFile(const FilePrx& file)
ex.reason = "cannot write `" + pathBZ2 + "':" + strerror(errno);
throw ex;
}
+
+ if (static_cast<Int>(bytesBZ2.size()) < num)
+ {
+ break;
+ }
+
+ progressCB.update(totalBZ2, pos);
}
- fileBZ2.close();
+
+ progressCB.finished(totalBZ2);
}