diff options
author | Marc Laukien <marc@zeroc.com> | 2004-11-28 22:57:21 +0000 |
---|---|---|
committer | Marc Laukien <marc@zeroc.com> | 2004-11-28 22:57:21 +0000 |
commit | 30172b32f4560d346f30e745088dda6428041415 (patch) | |
tree | 511283ad4d992f792928b3649f44bdbb623dae42 /cpp/src/IcePatch2/Client.cpp | |
parent | Glacier2 was missing from Slice directories (diff) | |
download | ice-30172b32f4560d346f30e745088dda6428041415.tar.bz2 ice-30172b32f4560d346f30e745088dda6428041415.tar.xz ice-30172b32f4560d346f30e745088dda6428041415.zip |
IcePatch2 for WIN32
Diffstat (limited to 'cpp/src/IcePatch2/Client.cpp')
-rw-r--r-- | cpp/src/IcePatch2/Client.cpp | 461 |
1 files changed, 89 insertions, 372 deletions
diff --git a/cpp/src/IcePatch2/Client.cpp b/cpp/src/IcePatch2/Client.cpp index c9007287fc6..3331e4b5440 100644 --- a/cpp/src/IcePatch2/Client.cpp +++ b/cpp/src/IcePatch2/Client.cpp @@ -8,13 +8,8 @@ // ********************************************************************** #include <Ice/Application.h> -#include <IcePatch2/FileServerI.h> #include <IcePatch2/Util.h> -#include <fstream> - -#ifdef _WIN32 -# include <direct.h> -#endif +#include <IcePatch2/ClientUtil.h> using namespace std; using namespace Ice; @@ -37,32 +32,98 @@ private: }; -class DecompressorDestroyer +class TextPatcherFeedback : public PatcherFeedback { public: - DecompressorDestroyer(DecompressorPtr decompressor) : - _decompressor(decompressor) + virtual bool + noFileSummary(const string& reason) + { + cout << "Cannot load file summary:\n" << reason << endl; + string answer; + do + { + cout << "Do a thorough patch? (yes/no)" << endl; + cin >> answer; + transform(answer.begin(), answer.end(), answer.begin(), ::tolower); + if(answer == "no") + { + return false; + } + } + while(answer != "yes"); + return true; + } + + virtual bool + fileListStart() + { + _lastProgress = "0%"; + cout << "Getting list of files to patch: " << _lastProgress << flush; + return true; + } + + virtual bool + fileListProgress(Int percent) + { + for(unsigned int i = 0; i < _lastProgress.size(); ++i) + { + cout << '\b'; + } + ostringstream s; + s << percent << '%'; + _lastProgress = s.str(); + cout << _lastProgress << flush; + return true; + } + + virtual bool + fileListEnd() + { + cout << endl; + return true; + } + + virtual bool + patchStart(const string& path, Long size, Long totalProgress, Long totalSize) { + ostringstream s; + s << "0/" << size << " (" << totalProgress << '/' << totalSize << ')'; + _lastProgress = s.str(); + cout << getBasename(path) << ' ' << _lastProgress << flush; + return true; } - ~DecompressorDestroyer() + virtual bool + patchProgress(Long progress, Long size, Long totalProgress, Long totalSize) { - _decompressor->destroy(); - _decompressor->getThreadControl().join(); + for(unsigned int i = 0; i < _lastProgress.size(); ++i) + { + cout << '\b'; + } + ostringstream s; + s << progress << '/' << size << " (" << totalProgress << '/' << totalSize << ')'; + _lastProgress = s.str(); + cout << _lastProgress << flush; + return true; + } + + virtual bool + patchEnd() + { + cout << endl; + return true; } private: - const DecompressorPtr _decompressor; + string _lastProgress; }; int IcePatch2::Client::run(int argc, char* argv[]) { - bool thorough = false; - bool dry = false; - string dataDir; + PropertiesPtr properties = communicator()->getProperties(); for(int i = 1; i < argc; ++i) { @@ -78,11 +139,11 @@ IcePatch2::Client::run(int argc, char* argv[]) } else if(strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--thorough") == 0) { - thorough = true; + properties->setProperty("IcePatch2.Thorough", "1"); } else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--dry") == 0) { - dry = true; + properties->setProperty("IcePatch2.DryRun", "1"); } else if(argv[i][0] == '-') { @@ -92,9 +153,9 @@ IcePatch2::Client::run(int argc, char* argv[]) } else { - if(dataDir.empty()) + if(properties->getProperty("IcePatch2.Directory").empty()) { - dataDir = argv[i]; + properties->setProperty("IcePatch2.Directory", argv[i]); } else { @@ -105,366 +166,22 @@ IcePatch2::Client::run(int argc, char* argv[]) } } - PropertiesPtr properties = communicator()->getProperties(); - - if(dataDir.empty()) - { - string dataDir = properties->getProperty("IcePatch2.Directory"); - if(dataDir.empty()) - { - cerr << argv[0] << ": no data directory specified" << endl; - usage(argv[0]); - return EXIT_FAILURE; - } - } - - Int chunk = properties->getPropertyAsIntWithDefault("IcePatch2.ChunkSize", 100000); - if(chunk < 1) - { - chunk = 1; - } - try { - FileInfoSeq infoSeq; - -#ifdef _WIN32 - char cwd[_MAX_PATH]; - if(_getcwd(cwd, _MAX_PATH) == NULL) -#else - char cwd[PATH_MAX]; - if(getcwd(cwd, PATH_MAX) == NULL) -#endif - { - throw string("cannot get the current directory: ") + strerror(errno); - } - - dataDir = normalize(string(cwd) + '/' + dataDir); - - if(chdir(dataDir.c_str()) == -1) - { - throw "cannot change directory to `" + dataDir + "': " + strerror(errno); - } - - if(!thorough) - { - try - { - loadFileInfoSeq(dataDir, infoSeq); - } - catch(const string& ex) - { - cout << "Cannot load file summary:\n" << ex << endl; - string answer; - do - { - cout << "Do a thorough patch? (yes/no)" << endl; - cin >> answer; - transform(answer.begin(), answer.end(), answer.begin(), ::tolower); - if(answer == "no") - { - return EXIT_SUCCESS; - } - } - while(answer != "yes"); - thorough = true; - } - } - - if(thorough) - { - getFileInfoSeq(".", infoSeq, false, false, false); - saveFileInfoSeq(dataDir, infoSeq); - } - - const char* endpointsProperty = "IcePatch2.Endpoints"; - const string endpoints = properties->getProperty(endpointsProperty); - if(endpoints.empty()) - { - cerr << argv[0] << ": property `" << endpointsProperty << "' is not set" << endl; - return EXIT_FAILURE; - } - - const char* idProperty = "IcePatch2.Identity"; - const Identity id = stringToIdentity(properties->getPropertyWithDefault(idProperty, "IcePatch2/server")); - - ObjectPrx fileServerBase = communicator()->stringToProxy(identityToString(id) + ':' + endpoints); - FileServerPrx fileServer = FileServerPrx::checkedCast(fileServerBase); - if(!fileServer) - { - cerr << argv[0] << ": proxy `" << identityToString(id) << ':' << endpoints << "' is not a file server." - << endl; - return EXIT_FAILURE; - } - - FileTree0 tree0; - getFileTree0(infoSeq, tree0); - - FileInfoSeq removeFiles; - FileInfoSeq updateFiles; - - ByteSeq empty(20, 0); - - if(tree0.checksum != fileServer->getChecksum()) - { - string progress = "0%"; - cout << "Getting list of files to patch: " << progress << flush; - - ByteSeqSeq checksum0Seq = fileServer->getChecksum0Seq(); - if(checksum0Seq.size() != 256) - { - cerr << argv[0] << ": server returned illegal value" << endl; - return EXIT_FAILURE; - } - - for(int node0 = 0; node0 < 256; ++node0) - { - if(tree0.nodes[node0].checksum != checksum0Seq[node0]) - { - FileInfoSeq fileSeq = fileServer->getFileInfo1Seq(node0); - - sort(fileSeq.begin(), fileSeq.end(), FileInfoLess()); - fileSeq.erase(unique(fileSeq.begin(), fileSeq.end(), FileInfoEqual()), fileSeq.end()); - - set_difference(tree0.nodes[node0].files.begin(), - tree0.nodes[node0].files.end(), - fileSeq.begin(), - fileSeq.end(), - back_inserter(removeFiles), - FileInfoLess()); - - set_difference(fileSeq.begin(), - fileSeq.end(), - tree0.nodes[node0].files.begin(), - tree0.nodes[node0].files.end(), - back_inserter(updateFiles), - FileInfoLess()); - } - - for(unsigned int i = 0; i < progress.size(); ++i) - { - cout << '\b'; - } - ostringstream s; - s << (node0 + 1) * 100 / 256 << '%'; - progress = s.str(); - cout << progress << flush; - } - } - - cout << endl; - - sort(removeFiles.begin(), removeFiles.end(), FileInfoLess()); - sort(updateFiles.begin(), updateFiles.end(), FileInfoLess()); - - FileInfoSeq::const_iterator p; - - if(!removeFiles.empty()) - { - p = removeFiles.begin(); - while(p != removeFiles.end()) - { - cout << "remove: " << getBasename(p->path) << endl; - - if(!dry) - { - try - { - removeRecursive(p->path); - } - catch(const string&) - { - } - } - - string dir = p->path + '/'; - - do - { - ++p; - } - while(p != removeFiles.end() && p->path.size() > dir.size() && - p->path.compare(0, dir.size(), dir) == 0); - } - - if(!dry) - { - FileInfoSeq newInfoSeq; - newInfoSeq.reserve(infoSeq.size()); - - set_difference(infoSeq.begin(), - infoSeq.end(), - removeFiles.begin(), - removeFiles.end(), - back_inserter(newInfoSeq), - FileInfoLess()); - - infoSeq.swap(newInfoSeq); - - saveFileInfoSeq(dataDir, infoSeq); - } - } - - if(!updateFiles.empty()) - { - string pathLog = dataDir + ".log"; - ofstream fileLog; - - if(!dry) - { - fileLog.open(pathLog.c_str()); - if(!fileLog) - { - cerr << argv[0] << ": cannot open `" + pathLog + "' for writing: " + strerror(errno); - return EXIT_FAILURE; - } - } - - Long total = 0; - Long updated = 0; - - for(p = updateFiles.begin(); p != updateFiles.end(); ++p) - { - if(p->size > 0) // Regular, non-empty file? - { - total += p->size; - } - } - - DecompressorPtr decompressor = new Decompressor; - DecompressorDestroyer decompressorDestroyer(decompressor); - decompressor->start(); - - for(p = updateFiles.begin(); p != updateFiles.end(); ++p) - { - cout << "update: " << getBasename(p->path) << ' ' << flush; - - if(p->size < 0) // Directory? - { - if(!dry) - { - createDirectoryRecursive(p->path); - fileLog << *p << endl; - } - } - else // Regular file. - { - string pathBZ2 = p->path + ".bz2"; - ofstream fileBZ2; - - if(!dry) - { - string dir = getDirname(pathBZ2); - if(!dir.empty()) - { - createDirectoryRecursive(dir); - } - - try - { - removeRecursive(pathBZ2); - } - catch(...) - { - } - - fileBZ2.open(pathBZ2.c_str(), ios::binary); - if(!fileBZ2) - { - cerr << argv[0] << ": cannot open `" + pathBZ2 + "' for writing: " + strerror(errno); - return EXIT_FAILURE; - } - } - - Int pos = 0; - string progress; - - while(pos < p->size) - { - ByteSeq bytes; - - try - { - bytes = fileServer->getFileCompressed(p->path, pos, chunk); - } - catch(const FileAccessException& ex) - { - cerr << argv[0] << ": server error for `" << p->path << "':" << ex.reason << endl; - return EXIT_FAILURE; - } - - if(bytes.empty()) - { - cerr << argv[0] << ": size mismatch for `" << p->path << "'" << endl; - return EXIT_FAILURE; - } - - if(!dry) - { - fileBZ2.write(reinterpret_cast<char*>(&bytes[0]), bytes.size()); - - if(!fileBZ2) - { - cerr << argv[0] << ": cannot write `" + pathBZ2 + "': " + strerror(errno); - return EXIT_FAILURE; - } - } - - pos += bytes.size(); - updated += bytes.size(); - - for(unsigned int i = 0; i < progress.size(); ++i) - { - cout << '\b'; - } - ostringstream s; - s << pos << '/' << p->size << " (" << updated << '/' << total << ')'; - progress = s.str(); - cout << progress << flush; - } - - if(!dry) - { - fileBZ2.close(); - fileLog << *p << endl; - - decompressor->checkForException(); - decompressor->add(p->path); - } - } - - cout << endl; - } - - decompressor->destroy(); - decompressor->getThreadControl().join(); - decompressor->checkForException(); - - if(!dry) - { - fileLog.close(); - - FileInfoSeq newInfoSeq; - newInfoSeq.reserve(infoSeq.size()); - - set_union(infoSeq.begin(), - infoSeq.end(), - updateFiles.begin(), - updateFiles.end(), - back_inserter(newInfoSeq), - FileInfoLess()); - - infoSeq.swap(newInfoSeq); - - saveFileInfoSeq(dataDir, infoSeq); - } - } + PatcherFeedbackPtr feedback = new TextPatcherFeedback; + PatcherPtr patcher = new Patcher(communicator(), feedback); + patcher->patch(); } catch(const string& ex) { cerr << argv[0] << ": " << ex << endl; return EXIT_FAILURE; } + catch(const char* ex) + { + cerr << argv[0] << ": " << ex << endl; + return EXIT_FAILURE; + } return EXIT_SUCCESS; } |