diff options
author | Marc Laukien <marc@zeroc.com> | 2002-04-15 19:12:57 +0000 |
---|---|---|
committer | Marc Laukien <marc@zeroc.com> | 2002-04-15 19:12:57 +0000 |
commit | 5f30d7093499c65b10a8458cf68cf9a585262236 (patch) | |
tree | b6ae5af4b1ac7ba89c383bdfd3cb8486fd44e737 /cpp/src | |
parent | Added PrivateKeyException to the addKeyCert methods to ensure that the (diff) | |
download | ice-5f30d7093499c65b10a8458cf68cf9a585262236.tar.bz2 ice-5f30d7093499c65b10a8458cf68cf9a585262236.tar.xz ice-5f30d7093499c65b10a8458cf68cf9a585262236.zip |
added pw check to glacier
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Glacier/GlacierI.cpp | 48 | ||||
-rw-r--r-- | cpp/src/Glacier/GlacierI.h | 17 | ||||
-rw-r--r-- | cpp/src/Glacier/GlacierRouter.cpp | 12 | ||||
-rw-r--r-- | cpp/src/Glacier/GlacierStarter.cpp | 79 | ||||
-rw-r--r-- | cpp/src/IcePatch/Client.cpp | 654 | ||||
-rw-r--r-- | cpp/src/IcePatch/FileDescFactory.cpp | 76 | ||||
-rw-r--r-- | cpp/src/IcePatch/FileLocator.cpp | 198 | ||||
-rw-r--r-- | cpp/src/IcePatch/IcePatchI.cpp | 186 | ||||
-rw-r--r-- | cpp/src/IcePatch/Server.cpp | 410 | ||||
-rw-r--r-- | cpp/src/IcePatch/Util.cpp | 1376 |
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); +} |