summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Glacier/GlacierI.cpp48
-rw-r--r--cpp/src/Glacier/GlacierI.h17
-rw-r--r--cpp/src/Glacier/GlacierRouter.cpp12
-rw-r--r--cpp/src/Glacier/GlacierStarter.cpp79
-rw-r--r--cpp/src/IcePatch/Client.cpp654
-rw-r--r--cpp/src/IcePatch/FileDescFactory.cpp76
-rw-r--r--cpp/src/IcePatch/FileLocator.cpp198
-rw-r--r--cpp/src/IcePatch/IcePatchI.cpp186
-rw-r--r--cpp/src/IcePatch/Server.cpp410
-rw-r--r--cpp/src/IcePatch/Util.cpp1376
10 files changed, 1581 insertions, 1475 deletions
diff --git a/cpp/src/Glacier/GlacierI.cpp b/cpp/src/Glacier/GlacierI.cpp
index b7f6984f5e9..0c349062f9d 100644
--- a/cpp/src/Glacier/GlacierI.cpp
+++ b/cpp/src/Glacier/GlacierI.cpp
@@ -16,6 +16,7 @@
#include <Ice/RSAKeyPair.h>
#include <Glacier/GlacierI.h>
#include <fcntl.h>
+#include <shadow.h>
using namespace std;
using namespace Ice;
@@ -23,11 +24,14 @@ using namespace Glacier;
using IceSSL::OpenSSL::RSAKeyPairPtr;
-Glacier::StarterI::StarterI(const CommunicatorPtr& communicator) :
+Glacier::StarterI::StarterI(const CommunicatorPtr& communicator, const PasswordVerifierPrx& verifier) :
_communicator(communicator),
_logger(_communicator->getLogger()),
- _properties(_communicator->getProperties())
+ _properties(_communicator->getProperties()),
+ _verifier(verifier)
{
+ assert(_verifier);
+
_traceLevel = atoi(_properties->getProperty("Glacier.Trace.Starter").c_str());
// Set up the Certificate Generation context
@@ -71,9 +75,10 @@ Glacier::StarterI::startRouter(const string& userId, const string& password, Byt
{
assert(_communicator); // Destroyed?
- //
- // TODO: userId/password check.
- //
+ if (!_verifier->checkPassword(userId, password))
+ {
+ throw InvalidPasswordException();
+ }
//
// Create a certificate for the client and the router.
@@ -371,3 +376,36 @@ Glacier::StarterI::startRouter(const string& userId, const string& password, Byt
assert(false); // Should never be reached.
return 0; // To keep the compiler from complaining.
}
+
+Glacier::CryptPasswordVerifierI::CryptPasswordVerifierI(const map<string, string>& passwords) :
+ _passwords(passwords)
+{
+}
+
+bool
+Glacier::CryptPasswordVerifierI::checkPassword(const string& userId, const string& password, const Current&)
+{
+ map<string, string>::const_iterator p = _passwords.find(userId);
+
+ if (p == _passwords.end())
+ {
+ return false;
+ }
+
+ if (p->second.size() != 13) // Crypt passwords are 13 characters long.
+ {
+ return false;
+ }
+
+ {
+ IceUtil::Lock<IceUtil::Mutex> sync(*this); // Need a lock as crypt() is not reentrant.
+
+ return p->second == crypt(password.c_str(), p->second.substr(0, 2).c_str());
+ }
+}
+
+void
+Glacier::CryptPasswordVerifierI::destroy(const Current&)
+{
+ // Nothing to do.
+}
diff --git a/cpp/src/Glacier/GlacierI.h b/cpp/src/Glacier/GlacierI.h
index b3407de39c9..2343e0b146d 100644
--- a/cpp/src/Glacier/GlacierI.h
+++ b/cpp/src/Glacier/GlacierI.h
@@ -25,7 +25,7 @@ class StarterI : public Starter
{
public:
- StarterI(const Ice::CommunicatorPtr&);
+ StarterI(const Ice::CommunicatorPtr&, const PasswordVerifierPrx&);
void destroy();
@@ -41,11 +41,26 @@ private:
Ice::CommunicatorPtr _communicator;
Ice::LoggerPtr _logger;
Ice::PropertiesPtr _properties;
+ PasswordVerifierPrx _verifier;
int _traceLevel;
RSACertificateGenContext _certContext;
RSACertificateGen _certificateGenerator;
};
+class CryptPasswordVerifierI : public PasswordVerifier, public IceUtil::Mutex
+{
+public:
+
+ CryptPasswordVerifierI(const std::map<std::string, std::string>&);
+
+ virtual bool checkPassword(const std::string&, const std::string&, const Ice::Current&);
+ virtual void destroy(const Ice::Current&);
+
+private:
+
+ const std::map<std::string, std::string> _passwords;
+};
+
}
#endif
diff --git a/cpp/src/Glacier/GlacierRouter.cpp b/cpp/src/Glacier/GlacierRouter.cpp
index 142c9ab8cda..3d392fe2bbe 100644
--- a/cpp/src/Glacier/GlacierRouter.cpp
+++ b/cpp/src/Glacier/GlacierRouter.cpp
@@ -152,12 +152,12 @@ Glacier::Router::run(int argc, char* argv[])
}
//
- // Create routing table
+ // Create the routing table.
//
IceInternal::RoutingTablePtr routingTable = new IceInternal::RoutingTable;
//
- // Initialize Client Object Adapter
+ // Initialize the client object adapter.
//
const char* clientEndpointsProperty = "Glacier.Client.Endpoints";
string clientEndpoints = properties->getProperty(clientEndpointsProperty);
@@ -166,13 +166,12 @@ Glacier::Router::run(int argc, char* argv[])
cerr << appName() << ": property `" << clientEndpointsProperty << "' is not set" << endl;
return EXIT_FAILURE;
}
-
ObjectAdapterPtr clientAdapter = communicator()->createObjectAdapterFromProperty("Client",
clientEndpointsProperty);
clientAdapter->activate();
//
- // Initialize Server Object Adapter
+ // Initialize the server object adapter.
//
const char* serverEndpointsProperty = "Glacier.Server.Endpoints";
string serverEndpoints = properties->getProperty(serverEndpointsProperty);
@@ -190,7 +189,6 @@ Glacier::Router::run(int argc, char* argv[])
ObjectPtr clientBlobject = new ClientBlobject(communicator(), routingTable);
Ice::ServantLocatorPtr clientServantLocator = new Glacier::ServantLocator(clientBlobject);
clientAdapter->addServantLocator(clientServantLocator, "");
-
if (serverAdapter)
{
ObjectPtr serverBlobject = new ServerBlobject(clientAdapter);
@@ -199,7 +197,7 @@ Glacier::Router::run(int argc, char* argv[])
}
//
- // Initialize Router
+ // Initialize the router object adapter and the router object.
//
const char* routerEndpointsProperty = "Glacier.Router.Endpoints";
string routerEndpoints = properties->getProperty(routerEndpointsProperty);
@@ -208,14 +206,12 @@ Glacier::Router::run(int argc, char* argv[])
cerr << appName() << ": property `" << routerEndpointsProperty << "' is not set" << endl;
return EXIT_FAILURE;
}
-
const char* routerIdentityProperty = "Glacier.Router.Identity";
string routerIdentity = properties->getProperty(routerIdentityProperty);
if (routerIdentity.empty())
{
routerIdentity = "Glacier/router";
}
-
ObjectAdapterPtr routerAdapter =
communicator()->createObjectAdapterFromProperty("Router", routerEndpointsProperty);
RouterPtr router = new RouterI(clientAdapter, serverAdapter, routingTable);
diff --git a/cpp/src/Glacier/GlacierStarter.cpp b/cpp/src/Glacier/GlacierStarter.cpp
index 1e8c3002079..bedaa8192d7 100644
--- a/cpp/src/Glacier/GlacierStarter.cpp
+++ b/cpp/src/Glacier/GlacierStarter.cpp
@@ -16,6 +16,7 @@
#include <Glacier/GlacierI.h>
#include <signal.h>
#include <sys/wait.h>
+#include <fstream>
using namespace std;
using namespace Ice;
@@ -70,21 +71,76 @@ Glacier::Router::run(int argc, char* argv[])
PropertiesPtr properties = communicator()->getProperties();
//
- // Initialize Starter Object Adapter
+ // Initialize the object adapter.
//
- const char* starterEndpointsProperty = "Glacier.Starter.Endpoints";
- string starterEndpoints = properties->getProperty(starterEndpointsProperty);
- if (starterEndpoints.empty())
+ const char* endpointsProperty = "Glacier.Starter.Endpoints";
+ string endpoints = properties->getProperty(endpointsProperty);
+ if (endpoints.empty())
{
- cerr << appName() << ": property `" << starterEndpointsProperty << "' is not set" << endl;
+ cerr << appName() << ": property `" << endpointsProperty << "' is not set" << endl;
return EXIT_FAILURE;
}
+ ObjectAdapterPtr adapter = communicator()->createObjectAdapterFromProperty("Starter", endpointsProperty);
- ObjectAdapterPtr starterAdapter = communicator()->createObjectAdapterFromProperty("Starter",
- starterEndpointsProperty);
- StarterPtr starter = new StarterI(communicator());
- starterAdapter->add(starter, stringToIdentity("Glacier/starter"));
- starterAdapter->activate();
+ //
+ // Get the password verifier, or create one if no verifier is
+ // specified.
+ //
+ string verifierProperty = properties->getProperty("Glacier.Starter.PasswordVerifier");
+ PasswordVerifierPrx verifier;
+ if (!verifierProperty.empty())
+ {
+ verifier = PasswordVerifierPrx::checkedCast(communicator()->stringToProxy(verifierProperty));
+ if (!verifier)
+ {
+ cerr << appName() << ": password verifier `" << verifierProperty << "' is invalid" << endl;
+ return EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ string passwordsProperty = properties->getPropertyWithDefault("Glacier.Starter.CryptPasswords", "passwords");
+
+ ifstream passwordFile(passwordsProperty.c_str());
+ if (!passwordFile)
+ {
+ cerr << appName() << ": cannot open `" << passwordsProperty << "' for reading: " << strerror(errno)
+ << endl;
+ return EXIT_FAILURE;
+ }
+
+ map<string, string> passwords;
+
+ while(true)
+ {
+ string userId;
+ passwordFile >> userId;
+ if (!passwordFile)
+ {
+ break;
+ }
+
+ string password;
+ passwordFile >> password;
+ if (!passwordFile)
+ {
+ break;
+ }
+
+ assert(!userId.empty());
+ assert(!password.empty());
+ passwords.insert(make_pair(userId, password));
+ }
+
+ verifier = PasswordVerifierPrx::uncheckedCast(adapter->addWithUUID(new CryptPasswordVerifierI(passwords)));
+ }
+
+ //
+ // Create the starter object and activate the object adapter.
+ //
+ StarterPtr starter = new StarterI(communicator(), verifier);
+ adapter->add(starter, stringToIdentity("Glacier/starter"));
+ adapter->activate();
//
// We're done, let's wait for shutdown.
@@ -92,11 +148,12 @@ Glacier::Router::run(int argc, char* argv[])
communicator()->waitForShutdown();
//
- // Destroy the starter.
+ // Destroy the starter and the password verifier.
//
StarterI* st = dynamic_cast<StarterI*>(starter.get());
assert(st);
st->destroy();
+ verifier->destroy();
return EXIT_SUCCESS;
}
diff --git a/cpp/src/IcePatch/Client.cpp b/cpp/src/IcePatch/Client.cpp
index 5161e887151..f5ea8c0602c 100644
--- a/cpp/src/IcePatch/Client.cpp
+++ b/cpp/src/IcePatch/Client.cpp
@@ -1,327 +1,327 @@
-// **********************************************************************
-//
-// Copyright (c) 2002
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <Ice/Application.h>
-#include <IcePatch/FileDescFactory.h>
-#include <IcePatch/Util.h>
-#include <iomanip>
-
-using namespace std;
-using namespace Ice;
-using namespace IcePatch;
-
-namespace IcePatch
-{
-
-class Client : public Application
-{
-public:
-
- void usage();
- virtual int run(int, char*[]);
-
- static string pathToName(const string&);
- static void patch(const FileDescSeq&, const string&);
-};
-
-};
-
-void
-IcePatch::Client::usage()
-{
- cerr << "Usage: " << appName() << " [options]\n";
- cerr <<
- "Options:\n"
- "-h, --help Show this message.\n"
- "-v, --version Display the Ice version.\n"
- ;
-}
-
-int
-IcePatch::Client::run(int argc, char* argv[])
-{
- try
- {
- for (int i = 1; i < argc; ++i)
- {
- if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
- {
- usage();
- return EXIT_SUCCESS;
- }
- else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
- {
- cout << ICE_STRING_VERSION << endl;
- return EXIT_SUCCESS;
- }
- else
- {
- cerr << appName() << ": unknown option `" << argv[i] << "'" << endl;
- usage();
- return EXIT_FAILURE;
- }
- }
-
- PropertiesPtr properties = communicator()->getProperties();
-
- //
- // Get the IcePatch endpoints.
- //
- const char* endpointsProperty = "IcePatch.Endpoints";
- string endpoints = properties->getProperty(endpointsProperty);
- if (endpoints.empty())
- {
- cerr << appName() << ": property `" << endpointsProperty << "' is not set" << endl;
- return EXIT_FAILURE;
- }
-
- //
- // Get the working directory and change to this directory.
- //
- const char* directoryProperty = "IcePatch.Directory";
- string directory = properties->getProperty(directoryProperty);
- if (!directory.empty())
- {
- changeDirectory(directory);
- }
-
- //
- // Create and install the node description factory.
- //
- ObjectFactoryPtr factory = new FileDescFactory;
- communicator()->addObjectFactory(factory, "::IcePatch::DirectoryDesc");
- communicator()->addObjectFactory(factory, "::IcePatch::RegularDesc");
-
- //
- // Patch all files.
- //
- Identity identity = pathToIdentity(".");
- ObjectPrx topObj = communicator()->stringToProxy(identityToString(identity) + ':' + endpoints);
- FilePrx top = FilePrx::checkedCast(topObj);
- assert(top);
- DirectoryDescPtr topDesc = DirectoryDescPtr::dynamicCast(top->describe());
- assert(topDesc);
- string path = identityToPath(topDesc->directory->ice_getIdentity());
- cout << pathToName(path) << endl;
- cout << "|" << endl;
- patch(topDesc->directory->getContents(), "");
- }
- catch (const FileAccessException& ex)
- {
- cerr << appName() << ": " << ex << ":\n" << ex.reason << endl;
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
-string
-IcePatch::Client::pathToName(const string& path)
-{
- string::size_type pos = path.rfind('/');
- if (pos == string::npos)
- {
- return path;
- }
- else
- {
- return path.substr(pos + 1);
- }
-}
-
-class MyProgressCB : public ProgressCB
-{
-public:
-
- virtual void startDownload(Int)
- {
- cout << "download 0% " << flush;
- }
-
- virtual void updateDownload(Int total, Int pos)
- {
- Ice::Int percent = pos * 100 / total;
- cout << "\b\b\b\b\b" << setw(3) << percent << "% " << flush;
- }
-
- virtual void finishedDownload(Int total)
- {
- cout << "\b\b\b\b\b" << "100% " << flush;
- }
-
- virtual void startUncompress(Int)
- {
- cout << "uncompress 0% " << flush;
- }
-
- virtual void updateUncompress(Int total, Int pos)
- {
- updateDownload(total, pos);
- }
-
- virtual void finishedUncompress(Int total)
- {
- finishedDownload(total);
- }
-};
-
-void
-IcePatch::Client::patch(const FileDescSeq& fileDescSeq, const string& indent)
-{
- if (fileDescSeq.empty())
- {
- return;
- }
-
- for (unsigned int i = 0; i < fileDescSeq.size(); ++i)
- {
- string path;
- DirectoryDescPtr directoryDesc = DirectoryDescPtr::dynamicCast(fileDescSeq[i]);
- RegularDescPtr regularDesc;
- if (directoryDesc)
- {
- path = identityToPath(directoryDesc->directory->ice_getIdentity());
- }
- else
- {
- regularDesc = RegularDescPtr::dynamicCast(fileDescSeq[i]);
- assert(regularDesc);
- path = identityToPath(regularDesc->regular->ice_getIdentity());
- }
-
- bool last = (i == fileDescSeq.size() - 1);
-
- if (directoryDesc)
- {
- string newIndent;
- if (last)
- {
- newIndent = indent + " ";
- }
- else
- {
- newIndent = indent + "| ";
- }
- cout << indent << "+-" << pathToName(path) << ": " << flush;
-
- FileInfo info = getFileInfo(path, false);
- switch (info.type)
- {
- case FileTypeNotExist:
- {
- cout << "creating directory... " << flush;
- createDirectory(path);
- break;
- }
-
- case FileTypeDirectory:
- {
- break;
- }
-
- case FileTypeRegular:
- {
- cout << "removing file... " << flush;
- removeRecursive(path);
- cout << "creating directory... " << flush;
- createDirectory(path);
- break;
- }
-
- case FileTypeUnknown:
- {
- cout << "removing unknown file... " << flush;
- removeRecursive(path);
- cout << "creating directory... " << flush;
- createDirectory(path);
- break;
- }
- }
-
- cout << "ok" << endl;
-
- cout << newIndent << "|" << endl;
- patch(directoryDesc->directory->getContents(), newIndent);
- }
- else
- {
- assert(regularDesc);
- cout << indent << "+-" << pathToName(path) << ": " << flush;
-
- MyProgressCB progressCB;
-
- FileInfo info = getFileInfo(path, false);
- switch (info.type)
- {
- case FileTypeNotExist:
- {
- cout << "getting file... " << flush;
- getRegular(regularDesc->regular, progressCB);
- break;
- }
-
- case FileTypeDirectory:
- {
- cout << "removing directory... " << flush;
- removeRecursive(path);
- cout << "getting file... " << flush;
- getRegular(regularDesc->regular, progressCB);
- break;
- }
-
- case FileTypeRegular:
- {
- ByteSeq md5;
-
- string pathMD5 = path + ".md5";
- FileInfo infoMD5 = getFileInfo(pathMD5, false);
- if (infoMD5.type == FileTypeRegular && infoMD5.time >= info.time)
- {
- md5 = getMD5(path);
- }
-
- if (md5 != regularDesc->md5)
- {
- cout << "removing file... " << flush;
- removeRecursive(path);
- cout << "getting file... " << flush;
- getRegular(regularDesc->regular, progressCB);
- }
-
- break;
- }
-
- case FileTypeUnknown:
- {
- cout << "removing unknown file... " << flush;
- removeRecursive(path);
- cout << "getting file... " << flush;
- getRegular(regularDesc->regular, progressCB);
- break;
- }
- }
-
- cout << "ok" << endl;
-
- if (last)
- {
- cout << indent << endl;
- }
- }
- }
-}
-
-int
-main(int argc, char* argv[])
-{
- addArgumentPrefix("IcePatch");
- Client app;
- return app.main(argc, argv);
-}
+// **********************************************************************
+//
+// Copyright (c) 2002
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/Application.h>
+#include <IcePatch/FileDescFactory.h>
+#include <IcePatch/Util.h>
+#include <iomanip>
+
+using namespace std;
+using namespace Ice;
+using namespace IcePatch;
+
+namespace IcePatch
+{
+
+class Client : public Application
+{
+public:
+
+ void usage();
+ virtual int run(int, char*[]);
+
+ static string pathToName(const string&);
+ static void patch(const FileDescSeq&, const string&);
+};
+
+};
+
+void
+IcePatch::Client::usage()
+{
+ cerr << "Usage: " << appName() << " [options]\n";
+ cerr <<
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ ;
+}
+
+int
+IcePatch::Client::run(int argc, char* argv[])
+{
+ try
+ {
+ for (int i = 1; i < argc; ++i)
+ {
+ if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
+ {
+ usage();
+ return EXIT_SUCCESS;
+ }
+ else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
+ {
+ cout << ICE_STRING_VERSION << endl;
+ return EXIT_SUCCESS;
+ }
+ else
+ {
+ cerr << appName() << ": unknown option `" << argv[i] << "'" << endl;
+ usage();
+ return EXIT_FAILURE;
+ }
+ }
+
+ PropertiesPtr properties = communicator()->getProperties();
+
+ //
+ // Get the IcePatch endpoints.
+ //
+ const char* endpointsProperty = "IcePatch.Endpoints";
+ string endpoints = properties->getProperty(endpointsProperty);
+ if (endpoints.empty())
+ {
+ cerr << appName() << ": property `" << endpointsProperty << "' is not set" << endl;
+ return EXIT_FAILURE;
+ }
+
+ //
+ // Get the working directory and change to this directory.
+ //
+ const char* directoryProperty = "IcePatch.Directory";
+ string directory = properties->getProperty(directoryProperty);
+ if (!directory.empty())
+ {
+ changeDirectory(directory);
+ }
+
+ //
+ // Create and install the node description factory.
+ //
+ ObjectFactoryPtr factory = new FileDescFactory;
+ communicator()->addObjectFactory(factory, "::IcePatch::DirectoryDesc");
+ communicator()->addObjectFactory(factory, "::IcePatch::RegularDesc");
+
+ //
+ // Patch all files.
+ //
+ Identity identity = pathToIdentity(".");
+ ObjectPrx topObj = communicator()->stringToProxy(identityToString(identity) + ':' + endpoints);
+ FilePrx top = FilePrx::checkedCast(topObj);
+ assert(top);
+ DirectoryDescPtr topDesc = DirectoryDescPtr::dynamicCast(top->describe());
+ assert(topDesc);
+ string path = identityToPath(topDesc->directory->ice_getIdentity());
+ cout << pathToName(path) << endl;
+ cout << "|" << endl;
+ patch(topDesc->directory->getContents(), "");
+ }
+ catch (const FileAccessException& ex)
+ {
+ cerr << appName() << ": " << ex << ":\n" << ex.reason << endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+string
+IcePatch::Client::pathToName(const string& path)
+{
+ string::size_type pos = path.rfind('/');
+ if (pos == string::npos)
+ {
+ return path;
+ }
+ else
+ {
+ return path.substr(pos + 1);
+ }
+}
+
+class MyProgressCB : public ProgressCB
+{
+public:
+
+ virtual void startDownload(Int)
+ {
+ cout << "download 0% " << flush;
+ }
+
+ virtual void updateDownload(Int total, Int pos)
+ {
+ Ice::Int percent = pos * 100 / total;
+ cout << "\b\b\b\b\b" << setw(3) << percent << "% " << flush;
+ }
+
+ virtual void finishedDownload(Int total)
+ {
+ cout << "\b\b\b\b\b" << "100% " << flush;
+ }
+
+ virtual void startUncompress(Int)
+ {
+ cout << "uncompress 0% " << flush;
+ }
+
+ virtual void updateUncompress(Int total, Int pos)
+ {
+ updateDownload(total, pos);
+ }
+
+ virtual void finishedUncompress(Int total)
+ {
+ finishedDownload(total);
+ }
+};
+
+void
+IcePatch::Client::patch(const FileDescSeq& fileDescSeq, const string& indent)
+{
+ if (fileDescSeq.empty())
+ {
+ return;
+ }
+
+ for (unsigned int i = 0; i < fileDescSeq.size(); ++i)
+ {
+ string path;
+ DirectoryDescPtr directoryDesc = DirectoryDescPtr::dynamicCast(fileDescSeq[i]);
+ RegularDescPtr regularDesc;
+ if (directoryDesc)
+ {
+ path = identityToPath(directoryDesc->directory->ice_getIdentity());
+ }
+ else
+ {
+ regularDesc = RegularDescPtr::dynamicCast(fileDescSeq[i]);
+ assert(regularDesc);
+ path = identityToPath(regularDesc->regular->ice_getIdentity());
+ }
+
+ bool last = (i == fileDescSeq.size() - 1);
+
+ if (directoryDesc)
+ {
+ string newIndent;
+ if (last)
+ {
+ newIndent = indent + " ";
+ }
+ else
+ {
+ newIndent = indent + "| ";
+ }
+ cout << indent << "+-" << pathToName(path) << ": " << flush;
+
+ FileInfo info = getFileInfo(path, false);
+ switch (info.type)
+ {
+ case FileTypeNotExist:
+ {
+ cout << "creating directory... " << flush;
+ createDirectory(path);
+ break;
+ }
+
+ case FileTypeDirectory:
+ {
+ break;
+ }
+
+ case FileTypeRegular:
+ {
+ cout << "removing file... " << flush;
+ removeRecursive(path);
+ cout << "creating directory... " << flush;
+ createDirectory(path);
+ break;
+ }
+
+ case FileTypeUnknown:
+ {
+ cout << "removing unknown file... " << flush;
+ removeRecursive(path);
+ cout << "creating directory... " << flush;
+ createDirectory(path);
+ break;
+ }
+ }
+
+ cout << "ok" << endl;
+
+ cout << newIndent << "|" << endl;
+ patch(directoryDesc->directory->getContents(), newIndent);
+ }
+ else
+ {
+ assert(regularDesc);
+ cout << indent << "+-" << pathToName(path) << ": " << flush;
+
+ MyProgressCB progressCB;
+
+ FileInfo info = getFileInfo(path, false);
+ switch (info.type)
+ {
+ case FileTypeNotExist:
+ {
+ cout << "getting file... " << flush;
+ getRegular(regularDesc->regular, progressCB);
+ break;
+ }
+
+ case FileTypeDirectory:
+ {
+ cout << "removing directory... " << flush;
+ removeRecursive(path);
+ cout << "getting file... " << flush;
+ getRegular(regularDesc->regular, progressCB);
+ break;
+ }
+
+ case FileTypeRegular:
+ {
+ ByteSeq md5;
+
+ string pathMD5 = path + ".md5";
+ FileInfo infoMD5 = getFileInfo(pathMD5, false);
+ if (infoMD5.type == FileTypeRegular && infoMD5.time >= info.time)
+ {
+ md5 = getMD5(path);
+ }
+
+ if (md5 != regularDesc->md5)
+ {
+ cout << "removing file... " << flush;
+ removeRecursive(path);
+ cout << "getting file... " << flush;
+ getRegular(regularDesc->regular, progressCB);
+ }
+
+ break;
+ }
+
+ case FileTypeUnknown:
+ {
+ cout << "removing unknown file... " << flush;
+ removeRecursive(path);
+ cout << "getting file... " << flush;
+ getRegular(regularDesc->regular, progressCB);
+ break;
+ }
+ }
+
+ cout << "ok" << endl;
+
+ if (last)
+ {
+ cout << indent << endl;
+ }
+ }
+ }
+}
+
+int
+main(int argc, char* argv[])
+{
+ addArgumentPrefix("IcePatch");
+ Client app;
+ return app.main(argc, argv);
+}
diff --git a/cpp/src/IcePatch/FileDescFactory.cpp b/cpp/src/IcePatch/FileDescFactory.cpp
index 4b7c9fc442e..76044fd700d 100644
--- a/cpp/src/IcePatch/FileDescFactory.cpp
+++ b/cpp/src/IcePatch/FileDescFactory.cpp
@@ -1,38 +1,38 @@
-// **********************************************************************
-//
-// Copyright (c) 2002
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IcePatch/FileDescFactory.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IcePatch;
-
-ObjectPtr
-IcePatch::FileDescFactory::create(const std::string& type)
-{
- if (type == "::IcePatch::DirectoryDesc")
- {
- return new DirectoryDesc;
- }
-
- if (type == "::IcePatch::RegularDesc")
- {
- return new RegularDesc;
- }
-
- assert(false);
- return 0; // To keep the compiler from complaining.
-}
-
-void
-IcePatch::FileDescFactory::destroy()
-{
- // Nothing to do.
-}
+// **********************************************************************
+//
+// Copyright (c) 2002
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IcePatch/FileDescFactory.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IcePatch;
+
+ObjectPtr
+IcePatch::FileDescFactory::create(const std::string& type)
+{
+ if (type == "::IcePatch::DirectoryDesc")
+ {
+ return new DirectoryDesc;
+ }
+
+ if (type == "::IcePatch::RegularDesc")
+ {
+ return new RegularDesc;
+ }
+
+ assert(false);
+ return 0; // To keep the compiler from complaining.
+}
+
+void
+IcePatch::FileDescFactory::destroy()
+{
+ // Nothing to do.
+}
diff --git a/cpp/src/IcePatch/FileLocator.cpp b/cpp/src/IcePatch/FileLocator.cpp
index 182db254f85..cdd001cd84d 100644
--- a/cpp/src/IcePatch/FileLocator.cpp
+++ b/cpp/src/IcePatch/FileLocator.cpp
@@ -1,99 +1,99 @@
-// **********************************************************************
-//
-// Copyright (c) 2002
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IcePatch/FileLocator.h>
-#include <IcePatch/Util.h>
-#include <IcePatch/IcePatchI.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IcePatch;
-
-IcePatch::FileLocator::FileLocator(const Ice::ObjectAdapterPtr& adapter) :
- _directory(new DirectoryI(adapter)),
- _regular(new RegularI(adapter))
-{
-}
-
-ObjectPtr
-IcePatch::FileLocator::locate(const ObjectAdapterPtr& adapter, const Current& current, LocalObjectPtr&)
-{
- //
- // Check whether the path is valid.
- //
- string path = identityToPath(current.identity);
-
- if (path.empty())
- {
- return 0;
- }
-
- if (path[0] == '/') // Path must not start with '/'.
- {
- return 0;
- }
-
- if (path.find("..") != string::npos) // Path must not contain '..'.
- {
- return 0;
- }
-
- if (path.find(':') == 1) // Path cannot contain ':' as second character.
- {
- return 0;
- }
-
- FileInfo info;
- try
- {
- info = getFileInfo(path, true);
- }
- catch (const FileAccessException& ex)
- {
- Warning out(adapter->getCommunicator()->getLogger());
- out << ex << ":\n" << ex.reason;
- return 0;
- }
-
- switch (info.type)
- {
- case FileTypeDirectory:
- {
- return _directory;
- }
-
- case FileTypeRegular:
- {
- return _regular;
- }
-
- default:
- {
- return 0;
- }
- }
-}
-
-void
-IcePatch::FileLocator::finished(const ObjectAdapterPtr&, const Current& current, const ObjectPtr&,
- const LocalObjectPtr&)
-{
- // Nothing to do.
-}
-
-void
-IcePatch::FileLocator::deactivate()
-{
- //
- // Break cyclic dependencies.
- //
- _directory = 0;
- _regular = 0;
-}
+// **********************************************************************
+//
+// Copyright (c) 2002
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IcePatch/FileLocator.h>
+#include <IcePatch/Util.h>
+#include <IcePatch/IcePatchI.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IcePatch;
+
+IcePatch::FileLocator::FileLocator(const Ice::ObjectAdapterPtr& adapter) :
+ _directory(new DirectoryI(adapter)),
+ _regular(new RegularI(adapter))
+{
+}
+
+ObjectPtr
+IcePatch::FileLocator::locate(const ObjectAdapterPtr& adapter, const Current& current, LocalObjectPtr&)
+{
+ //
+ // Check whether the path is valid.
+ //
+ string path = identityToPath(current.identity);
+
+ if (path.empty())
+ {
+ return 0;
+ }
+
+ if (path[0] == '/') // Path must not start with '/'.
+ {
+ return 0;
+ }
+
+ if (path.find("..") != string::npos) // Path must not contain '..'.
+ {
+ return 0;
+ }
+
+ if (path.find(':') == 1) // Path cannot contain ':' as second character.
+ {
+ return 0;
+ }
+
+ FileInfo info;
+ try
+ {
+ info = getFileInfo(path, true);
+ }
+ catch (const FileAccessException& ex)
+ {
+ Warning out(adapter->getCommunicator()->getLogger());
+ out << ex << ":\n" << ex.reason;
+ return 0;
+ }
+
+ switch (info.type)
+ {
+ case FileTypeDirectory:
+ {
+ return _directory;
+ }
+
+ case FileTypeRegular:
+ {
+ return _regular;
+ }
+
+ default:
+ {
+ return 0;
+ }
+ }
+}
+
+void
+IcePatch::FileLocator::finished(const ObjectAdapterPtr&, const Current& current, const ObjectPtr&,
+ const LocalObjectPtr&)
+{
+ // Nothing to do.
+}
+
+void
+IcePatch::FileLocator::deactivate()
+{
+ //
+ // Break cyclic dependencies.
+ //
+ _directory = 0;
+ _regular = 0;
+}
diff --git a/cpp/src/IcePatch/IcePatchI.cpp b/cpp/src/IcePatch/IcePatchI.cpp
index 8e836f5df9b..54f33440c71 100644
--- a/cpp/src/IcePatch/IcePatchI.cpp
+++ b/cpp/src/IcePatch/IcePatchI.cpp
@@ -1,93 +1,93 @@
-// **********************************************************************
-//
-// Copyright (c) 2002
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IcePatch/IcePatchI.h>
-#include <IcePatch/Util.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IcePatch;
-
-IcePatch::FileI::FileI(const ObjectAdapterPtr& adapter) :
- _adapter(adapter)
-{
-}
-
-IcePatch::DirectoryI::DirectoryI(const ObjectAdapterPtr& adapter) :
- FileI(adapter)
-{
-}
-
-FileDescPtr
-IcePatch::DirectoryI::describe(const Ice::Current& current)
-{
- DirectoryDescPtr desc = new DirectoryDesc;
- desc->directory = DirectoryPrx::uncheckedCast(_adapter->createProxy(current.identity));
- return desc;
-}
-
-FileDescSeq
-IcePatch::DirectoryI::getContents(const Ice::Current& current)
-{
- StringSeq paths = readDirectory(identityToPath(current.identity));
-
- FileDescSeq result;
- result.reserve(paths.size());
-
- StringSeq::const_iterator p;
- for (p = paths.begin(); p != paths.end(); ++p)
- {
- if (ignoreSuffix(*p))
- {
- continue;
- }
-
- FilePrx file = FilePrx::uncheckedCast(_adapter->createProxy(pathToIdentity(*p)));
- try
- {
- result.push_back(file->describe());
- }
- catch (const ObjectNotExistException&)
- {
- //
- // Ignore. This can for example happen if the file
- // locator cannot call stat() on the file.
- //
- }
- }
-
- return result;
-}
-
-IcePatch::RegularI::RegularI(const ObjectAdapterPtr& adapter) :
- FileI(adapter)
-{
-}
-
-FileDescPtr
-IcePatch::RegularI::describe(const Ice::Current& current)
-{
- RegularDescPtr desc = new RegularDesc;
- desc->regular = RegularPrx::uncheckedCast(_adapter->createProxy(current.identity));
- desc->md5 = getMD5(identityToPath(current.identity));
- return desc;
-}
-
-Int
-IcePatch::RegularI::getBZ2Size(const Ice::Current& current)
-{
- return getFileInfo(identityToPath(current.identity) + ".bz2", true).size;
-}
-
-ByteSeq
-IcePatch::RegularI::getBZ2(Ice::Int pos, Ice::Int num, const Ice::Current& current)
-{
- return IcePatch::getBZ2(identityToPath(current.identity), pos, num);
-}
+// **********************************************************************
+//
+// Copyright (c) 2002
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IcePatch/IcePatchI.h>
+#include <IcePatch/Util.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IcePatch;
+
+IcePatch::FileI::FileI(const ObjectAdapterPtr& adapter) :
+ _adapter(adapter)
+{
+}
+
+IcePatch::DirectoryI::DirectoryI(const ObjectAdapterPtr& adapter) :
+ FileI(adapter)
+{
+}
+
+FileDescPtr
+IcePatch::DirectoryI::describe(const Ice::Current& current)
+{
+ DirectoryDescPtr desc = new DirectoryDesc;
+ desc->directory = DirectoryPrx::uncheckedCast(_adapter->createProxy(current.identity));
+ return desc;
+}
+
+FileDescSeq
+IcePatch::DirectoryI::getContents(const Ice::Current& current)
+{
+ StringSeq paths = readDirectory(identityToPath(current.identity));
+
+ FileDescSeq result;
+ result.reserve(paths.size());
+
+ StringSeq::const_iterator p;
+ for (p = paths.begin(); p != paths.end(); ++p)
+ {
+ if (ignoreSuffix(*p))
+ {
+ continue;
+ }
+
+ FilePrx file = FilePrx::uncheckedCast(_adapter->createProxy(pathToIdentity(*p)));
+ try
+ {
+ result.push_back(file->describe());
+ }
+ catch (const ObjectNotExistException&)
+ {
+ //
+ // Ignore. This can for example happen if the file
+ // locator cannot call stat() on the file.
+ //
+ }
+ }
+
+ return result;
+}
+
+IcePatch::RegularI::RegularI(const ObjectAdapterPtr& adapter) :
+ FileI(adapter)
+{
+}
+
+FileDescPtr
+IcePatch::RegularI::describe(const Ice::Current& current)
+{
+ RegularDescPtr desc = new RegularDesc;
+ desc->regular = RegularPrx::uncheckedCast(_adapter->createProxy(current.identity));
+ desc->md5 = getMD5(identityToPath(current.identity));
+ return desc;
+}
+
+Int
+IcePatch::RegularI::getBZ2Size(const Ice::Current& current)
+{
+ return getFileInfo(identityToPath(current.identity) + ".bz2", true).size;
+}
+
+ByteSeq
+IcePatch::RegularI::getBZ2(Ice::Int pos, Ice::Int num, const Ice::Current& current)
+{
+ return IcePatch::getBZ2(identityToPath(current.identity), pos, num);
+}
diff --git a/cpp/src/IcePatch/Server.cpp b/cpp/src/IcePatch/Server.cpp
index 931a7527d07..fadbf596b95 100644
--- a/cpp/src/IcePatch/Server.cpp
+++ b/cpp/src/IcePatch/Server.cpp
@@ -1,205 +1,205 @@
-// **********************************************************************
-//
-// Copyright (c) 2002
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <Ice/Application.h>
-#include <IcePatch/FileLocator.h>
-#include <IcePatch/Util.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IcePatch;
-
-namespace IcePatch
-{
-
-class Server : public Application
-{
-public:
-
- void usage();
- virtual int run(int, char*[]);
-
- static void removeOrphanedRecursive(const string&);
- static void updateRecursive(const string&);
-};
-
-};
-
-void
-IcePatch::Server::usage()
-{
- cerr << "Usage: " << appName() << " [options]\n";
- cerr <<
- "Options:\n"
- "-h, --help Show this message.\n"
- "-v, --version Display the Ice version.\n"
- ;
-}
-
-int
-IcePatch::Server::run(int argc, char* argv[])
-{
- try
- {
- for (int i = 1; i < argc; ++i)
- {
- if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
- {
- usage();
- return EXIT_SUCCESS;
- }
- else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
- {
- cout << ICE_STRING_VERSION << endl;
- return EXIT_SUCCESS;
- }
- else
- {
- cerr << appName() << ": unknown option `" << argv[i] << "'" << endl;
- usage();
- return EXIT_FAILURE;
- }
- }
-
- PropertiesPtr properties = communicator()->getProperties();
-
- //
- // Get the IcePatch endpoints.
- //
- const char* endpointsProperty = "IcePatch.Endpoints";
- string endpoints = properties->getProperty(endpointsProperty);
- if (endpoints.empty())
- {
- cerr << appName() << ": property `" << endpointsProperty << "' is not set" << endl;
- return EXIT_FAILURE;
- }
-
- //
- // Get the working directory and change to this directory.
- //
- const char* directoryProperty = "IcePatch.Directory";
- string directory = properties->getProperty(directoryProperty);
- if (!directory.empty())
- {
- changeDirectory(directory);
- }
-
- //
- // Remove orphaned MD5 and BZ2 files.
- // Create MD5 and BZ2 files.
- //
- removeOrphanedRecursive(".");
- updateRecursive(".");
-
- //
- // Create and initialize the object adapter and the file locator.
- //
- ObjectAdapterPtr adapter = communicator()->createObjectAdapterFromProperty("IcePatch", endpointsProperty);
- ServantLocatorPtr fileLocator = new FileLocator(adapter);
- adapter->addServantLocator(fileLocator, "IcePatch");
- adapter->activate();
-
- //
- // We're done, let's wait for shutdown.
- //
- communicator()->waitForShutdown();
- }
- catch (const FileAccessException& ex)
- {
- cerr << appName() << ": " << ex << ":\n" << ex.reason << endl;
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
-void
-IcePatch::Server::removeOrphanedRecursive(const string& path)
-{
- assert(getFileInfo(path, true).type == FileTypeDirectory);
-
- StringSeq paths = readDirectory(path);
- StringSeq::const_iterator p;
- for (p = paths.begin(); p != paths.end(); ++p)
- {
- if (ignoreSuffix(*p))
- {
- pair<StringSeq::const_iterator, StringSeq::const_iterator> r =
- equal_range(paths.begin(), paths.end(), removeSuffix(*p));
- if (r.first == r.second)
- {
- cout << "removing orphaned file `" << *p << "'... " << flush;
- removeRecursive(*p);
- cout << "ok" << endl;
- }
- }
- else
- {
- if (getFileInfo(*p, true).type == FileTypeDirectory)
- {
- removeOrphanedRecursive(*p);
- }
- }
- }
-
- if (readDirectory(path).empty())
- {
- cout << "removing empty directory `" << *p << "'... " << flush;
- removeRecursive(path);
- cout << "ok" << endl;
- }
-}
-
-void
-IcePatch::Server::updateRecursive(const string& path)
-{
- if (ignoreSuffix(path))
- {
- return;
- }
-
- FileInfo info = getFileInfo(path, true);
-
- if (info.type == FileTypeDirectory)
- {
- StringSeq paths = readDirectory(path);
- StringSeq::const_iterator p;
- for (p = paths.begin(); p != paths.end(); ++p)
- {
- updateRecursive(*p);
- }
- }
- else if (info.type == FileTypeRegular)
- {
- FileInfo infoMD5 = getFileInfo(path + ".md5", false);
- if (infoMD5.type != FileTypeRegular || infoMD5.time < info.time)
- {
- cout << "creating .md5 file for `" << path << "'... " << flush;
- createMD5(path);
- cout << "ok" << endl;
- }
-
- FileInfo infoBZ2 = getFileInfo(path + ".bz2", false);
- if (infoBZ2.type != FileTypeRegular || infoBZ2.time < info.time)
- {
- cout << "creating .bz2 file for `" << path << "'... " << flush;
- createBZ2(path);
- cout << "ok" << endl;
- }
- }
-}
-
-int
-main(int argc, char* argv[])
-{
- addArgumentPrefix("IcePatch");
- Server app;
- return app.main(argc, argv);
-}
+// **********************************************************************
+//
+// Copyright (c) 2002
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/Application.h>
+#include <IcePatch/FileLocator.h>
+#include <IcePatch/Util.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IcePatch;
+
+namespace IcePatch
+{
+
+class Server : public Application
+{
+public:
+
+ void usage();
+ virtual int run(int, char*[]);
+
+ static void removeOrphanedRecursive(const string&);
+ static void updateRecursive(const string&);
+};
+
+};
+
+void
+IcePatch::Server::usage()
+{
+ cerr << "Usage: " << appName() << " [options]\n";
+ cerr <<
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ ;
+}
+
+int
+IcePatch::Server::run(int argc, char* argv[])
+{
+ try
+ {
+ for (int i = 1; i < argc; ++i)
+ {
+ if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
+ {
+ usage();
+ return EXIT_SUCCESS;
+ }
+ else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
+ {
+ cout << ICE_STRING_VERSION << endl;
+ return EXIT_SUCCESS;
+ }
+ else
+ {
+ cerr << appName() << ": unknown option `" << argv[i] << "'" << endl;
+ usage();
+ return EXIT_FAILURE;
+ }
+ }
+
+ PropertiesPtr properties = communicator()->getProperties();
+
+ //
+ // Get the IcePatch endpoints.
+ //
+ const char* endpointsProperty = "IcePatch.Endpoints";
+ string endpoints = properties->getProperty(endpointsProperty);
+ if (endpoints.empty())
+ {
+ cerr << appName() << ": property `" << endpointsProperty << "' is not set" << endl;
+ return EXIT_FAILURE;
+ }
+
+ //
+ // Get the working directory and change to this directory.
+ //
+ const char* directoryProperty = "IcePatch.Directory";
+ string directory = properties->getProperty(directoryProperty);
+ if (!directory.empty())
+ {
+ changeDirectory(directory);
+ }
+
+ //
+ // Remove orphaned MD5 and BZ2 files.
+ // Create MD5 and BZ2 files.
+ //
+ removeOrphanedRecursive(".");
+ updateRecursive(".");
+
+ //
+ // Create and initialize the object adapter and the file locator.
+ //
+ ObjectAdapterPtr adapter = communicator()->createObjectAdapterFromProperty("IcePatch", endpointsProperty);
+ ServantLocatorPtr fileLocator = new FileLocator(adapter);
+ adapter->addServantLocator(fileLocator, "IcePatch");
+ adapter->activate();
+
+ //
+ // We're done, let's wait for shutdown.
+ //
+ communicator()->waitForShutdown();
+ }
+ catch (const FileAccessException& ex)
+ {
+ cerr << appName() << ": " << ex << ":\n" << ex.reason << endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+void
+IcePatch::Server::removeOrphanedRecursive(const string& path)
+{
+ assert(getFileInfo(path, true).type == FileTypeDirectory);
+
+ StringSeq paths = readDirectory(path);
+ StringSeq::const_iterator p;
+ for (p = paths.begin(); p != paths.end(); ++p)
+ {
+ if (ignoreSuffix(*p))
+ {
+ pair<StringSeq::const_iterator, StringSeq::const_iterator> r =
+ equal_range(paths.begin(), paths.end(), removeSuffix(*p));
+ if (r.first == r.second)
+ {
+ cout << "removing orphaned file `" << *p << "'... " << flush;
+ removeRecursive(*p);
+ cout << "ok" << endl;
+ }
+ }
+ else
+ {
+ if (getFileInfo(*p, true).type == FileTypeDirectory)
+ {
+ removeOrphanedRecursive(*p);
+ }
+ }
+ }
+
+ if (readDirectory(path).empty())
+ {
+ cout << "removing empty directory `" << *p << "'... " << flush;
+ removeRecursive(path);
+ cout << "ok" << endl;
+ }
+}
+
+void
+IcePatch::Server::updateRecursive(const string& path)
+{
+ if (ignoreSuffix(path))
+ {
+ return;
+ }
+
+ FileInfo info = getFileInfo(path, true);
+
+ if (info.type == FileTypeDirectory)
+ {
+ StringSeq paths = readDirectory(path);
+ StringSeq::const_iterator p;
+ for (p = paths.begin(); p != paths.end(); ++p)
+ {
+ updateRecursive(*p);
+ }
+ }
+ else if (info.type == FileTypeRegular)
+ {
+ FileInfo infoMD5 = getFileInfo(path + ".md5", false);
+ if (infoMD5.type != FileTypeRegular || infoMD5.time < info.time)
+ {
+ cout << "creating .md5 file for `" << path << "'... " << flush;
+ createMD5(path);
+ cout << "ok" << endl;
+ }
+
+ FileInfo infoBZ2 = getFileInfo(path + ".bz2", false);
+ if (infoBZ2.type != FileTypeRegular || infoBZ2.time < info.time)
+ {
+ cout << "creating .bz2 file for `" << path << "'... " << flush;
+ createBZ2(path);
+ cout << "ok" << endl;
+ }
+ }
+}
+
+int
+main(int argc, char* argv[])
+{
+ addArgumentPrefix("IcePatch");
+ Server app;
+ return app.main(argc, argv);
+}
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);
+}