diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/slice/IcePatch/IcePatch.ice | 7 | ||||
-rw-r--r-- | cpp/src/IcePatch/Client.cpp | 22 | ||||
-rw-r--r-- | cpp/src/IcePatch/IcePatchI.cpp | 115 | ||||
-rw-r--r-- | cpp/src/IcePatch/IcePatchI.h | 16 | ||||
-rw-r--r-- | cpp/src/IcePatch/Server.cpp | 15 | ||||
-rw-r--r-- | cpp/src/IcePatch/Util.cpp | 154 |
6 files changed, 112 insertions, 217 deletions
diff --git a/cpp/slice/IcePatch/IcePatch.ice b/cpp/slice/IcePatch/IcePatch.ice index c3b4e5896e9..9ddb3249a13 100644 --- a/cpp/slice/IcePatch/IcePatch.ice +++ b/cpp/slice/IcePatch/IcePatch.ice @@ -16,11 +16,6 @@ module IcePatch { -interface Info -{ - nonmutating long getStamp(); -}; - exception FileAccessException { string reason; @@ -32,6 +27,7 @@ exception BusyException class FileDesc { + Ice::ByteSeq md5; }; sequence<FileDesc> FileDescSeq; @@ -68,7 +64,6 @@ interface Regular extends File class RegularDesc extends FileDesc { Regular* regular; - Ice::ByteSeq md5; }; }; diff --git a/cpp/src/IcePatch/Client.cpp b/cpp/src/IcePatch/Client.cpp index bbf34ee8743..77bd242e154 100644 --- a/cpp/src/IcePatch/Client.cpp +++ b/cpp/src/IcePatch/Client.cpp @@ -196,26 +196,6 @@ IcePatch::Client::run(int argc, char* argv[]) } // - // Check whether we have to patch at all. - // - Identity infoIdentity = pathToIdentity(".icepatch"); - ObjectPrx infoObj = communicator()->stringToProxy(identityToString(infoIdentity) + ':' + endpoints); - InfoPrx info = InfoPrx::checkedCast(infoObj); - assert(info); - Long remoteStamp = info->getStamp(); - Long localStamp = readStamp(); - if(remoteStamp != localStamp) - { - localStamp = remoteStamp; - writeStamp(localStamp); - } - else if(!(properties->getPropertyAsInt("IcePatch.PatchAlways") > 0)) - { - cout << "You are up-to-date. No patching is necessary." << endl; - return EXIT_SUCCESS; - } - - // // Check whether we want to remove orphaned files. // _remove = properties->getPropertyAsInt("IcePatch.RemoveOrphaned") > 0; @@ -388,7 +368,7 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent) c orphaned.reserve(fullDirectoryListing.size()); for(StringSeq::const_iterator p = fullDirectoryListing.begin(); p != fullDirectoryListing.end(); ++p) { - if(*p != ".icepatch" && getSuffix(*p) != "md5") + if(getSuffix(*p) != "md5") { orphaned.push_back(*p); } diff --git a/cpp/src/IcePatch/IcePatchI.cpp b/cpp/src/IcePatch/IcePatchI.cpp index 19cd69e0203..5dbf5709caa 100644 --- a/cpp/src/IcePatch/IcePatchI.cpp +++ b/cpp/src/IcePatch/IcePatchI.cpp @@ -17,26 +17,54 @@ using namespace IcePatch; static IceUtil::RWRecMutex globalMutex; -IcePatch::InfoI::InfoI(const ObjectAdapterPtr& adapter) : +IcePatch::FileI::FileI(const ObjectAdapterPtr& adapter) : _adapter(adapter), + _logger(adapter->getCommunicator()->getLogger()), + _traceLevel(adapter->getCommunicator()->getProperties()->getPropertyAsInt("IcePatch.Trace.Files")), _busyTimeout(IceUtil::Time::seconds(adapter->getCommunicator()->getProperties()-> getPropertyAsIntWithDefault("IcePatch.BusyTimeout", 10))) { } -Long -IcePatch::InfoI::getStamp(const Current& current) const +ByteSeq +IcePatch::FileI::readMD5(const Current& current) const { - // - // ".icepatch" is our reserved name for the IcePatch info object, - // as well as for the directory that contains IcePatch info. - // - assert(current.id.name == ".icepatch"); + string path = identityToPath(current.id); + if(path == ".") + { + // + // We cannot create an MD5 file for the current directory. + // + return ByteSeq(); + } + try { IceUtil::RWRecMutex::TryRLock sync(globalMutex, _busyTimeout); - return readStamp(); + + FileInfo info = getFileInfo(path, true); + FileInfo infoMD5 = getFileInfo(path + ".md5", false); + + if(infoMD5.type != FileTypeRegular || infoMD5.time <= info.time) + { + sync.timedUpgrade(_busyTimeout); + + infoMD5 = getFileInfo(path + ".md5", false); + + if(infoMD5.type != FileTypeRegular || infoMD5.time <= info.time) + { + createMD5(path); + + if(_traceLevel > 0) + { + Trace out(_logger, "IcePatch"); + out << "created MD5 file for `" << path << "'"; + } + } + } + + return getMD5(path); } catch(const IceUtil::LockedException&) { @@ -44,15 +72,6 @@ IcePatch::InfoI::getStamp(const Current& current) const } } -IcePatch::FileI::FileI(const ObjectAdapterPtr& adapter) : - _adapter(adapter), - _logger(adapter->getCommunicator()->getLogger()), - _traceLevel(adapter->getCommunicator()->getProperties()->getPropertyAsInt("IcePatch.Trace.Files")), - _busyTimeout(IceUtil::Time::seconds(adapter->getCommunicator()->getProperties()-> - getPropertyAsIntWithDefault("IcePatch.BusyTimeout", 10))) -{ -} - IcePatch::DirectoryI::DirectoryI(const ObjectAdapterPtr& adapter) : FileI(adapter) { @@ -63,6 +82,7 @@ IcePatch::DirectoryI::describe(const Current& current) const { // No mutex lock necessary. DirectoryDescPtr desc = new DirectoryDesc; + desc->md5 = readMD5(current); desc->directory = DirectoryPrx::uncheckedCast(_adapter->createProxy(current.id)); return desc; } @@ -79,7 +99,6 @@ IcePatch::DirectoryI::getContents(const Current& current) const bool syncUpgraded = false; string path = identityToPath(current.id); StringSeq paths = readDirectory(path); - paths.erase(remove(paths.begin(), paths.end(), ".icepatch"), paths.end()); filteredPaths.reserve(paths.size() / 3); for(StringSeq::const_iterator p = paths.begin(); p != paths.end(); ++p) { @@ -95,7 +114,6 @@ IcePatch::DirectoryI::getContents(const Current& current) const syncUpgraded = true; } StringSeq paths2 = readDirectory(path); - paths2.erase(remove(paths2.begin(), paths2.end(), ".icepatch"), paths2.end()); pair<StringSeq::const_iterator, StringSeq::const_iterator> r2 = equal_range(paths2.begin(), paths2.end(), removeSuffix(*p)); if(r2.first == r2.second) @@ -153,42 +171,11 @@ IcePatch::RegularI::RegularI(const ObjectAdapterPtr& adapter) : FileDescPtr IcePatch::RegularI::describe(const Current& current) const { - try - { - IceUtil::RWRecMutex::TryRLock sync(globalMutex, _busyTimeout); - - string path = identityToPath(current.id); - FileInfo info = getFileInfo(path, true); - assert(info.type == FileTypeRegular); - - FileInfo infoMD5 = getFileInfo(path + ".md5", false); - if(infoMD5.type != FileTypeRegular || infoMD5.time <= info.time) - { - sync.timedUpgrade(_busyTimeout); - - infoMD5 = getFileInfo(path + ".md5", false); - if(infoMD5.type != FileTypeRegular || infoMD5.time <= info.time) - { - createMD5(path); - writeStamp(readStamp() + 1); - - if(_traceLevel > 0) - { - Trace out(_logger, "IcePatch"); - out << "created MD5 file for file `" << path << "'"; - } - } - } - - RegularDescPtr desc = new RegularDesc; - desc->md5 = getMD5(path); - desc->regular = RegularPrx::uncheckedCast(_adapter->createProxy(current.id)); - return desc; - } - catch(const IceUtil::LockedException&) - { - throw BusyException(); - } + // No mutex lock necessary. + RegularDescPtr desc = new RegularDesc; + desc->md5 = readMD5(current); + desc->regular = RegularPrx::uncheckedCast(_adapter->createProxy(current.id)); + return desc; } Int @@ -199,15 +186,17 @@ IcePatch::RegularI::getBZ2Size(const Current& current) const IceUtil::RWRecMutex::TryRLock sync(globalMutex, _busyTimeout); string path = identityToPath(current.id); + FileInfo info = getFileInfo(path, true); assert(info.type == FileTypeRegular); - FileInfo infoBZ2 = getFileInfo(path + ".bz2", false); + if(infoBZ2.type != FileTypeRegular || infoBZ2.time <= info.time) { sync.timedUpgrade(_busyTimeout); infoBZ2 = getFileInfo(path + ".bz2", false); + if(infoBZ2.type != FileTypeRegular || infoBZ2.time <= info.time) { createBZ2(path); @@ -243,15 +232,17 @@ IcePatch::RegularI::getBZ2(Int pos, Int num, const Current& current) const IceUtil::RWRecMutex::TryRLock sync(globalMutex, _busyTimeout); string path = identityToPath(current.id); + FileInfo info = getFileInfo(path, true); assert(info.type == FileTypeRegular); - FileInfo infoBZ2 = getFileInfo(path + ".bz2", false); + if(infoBZ2.type != FileTypeRegular || infoBZ2.time <= info.time) { sync.timedUpgrade(_busyTimeout); infoBZ2 = getFileInfo(path + ".bz2", false); + if(infoBZ2.type != FileTypeRegular || infoBZ2.time <= info.time) { createBZ2(path); @@ -259,7 +250,7 @@ IcePatch::RegularI::getBZ2(Int pos, Int num, const Current& current) const if(_traceLevel > 0) { Trace out(_logger, "IcePatch"); - out << "created .bz2 file for `" << path << "'"; + out << "created BZ2 file for `" << path << "'"; } } } @@ -280,15 +271,17 @@ IcePatch::RegularI::getBZ2MD5(Int size, const Current& current) const IceUtil::RWRecMutex::TryRLock sync(globalMutex, _busyTimeout); string path = identityToPath(current.id); + FileInfo info = getFileInfo(path, true); assert(info.type == FileTypeRegular); - FileInfo infoBZ2 = getFileInfo(path + ".bz2", false); + if(infoBZ2.type != FileTypeRegular || infoBZ2.time <= info.time) { sync.timedUpgrade(_busyTimeout); infoBZ2 = getFileInfo(path + ".bz2", false); + if(infoBZ2.type != FileTypeRegular || infoBZ2.time <= info.time) { createBZ2(path); @@ -296,7 +289,7 @@ IcePatch::RegularI::getBZ2MD5(Int size, const Current& current) const if(_traceLevel > 0) { Trace out(_logger, "IcePatch"); - out << "created .bz2 file for `" << path << "'"; + out << "created BZ2 file for `" << path << "'"; } } } diff --git a/cpp/src/IcePatch/IcePatchI.h b/cpp/src/IcePatch/IcePatchI.h index 69a6316e014..93fc286afbc 100644 --- a/cpp/src/IcePatch/IcePatchI.h +++ b/cpp/src/IcePatch/IcePatchI.h @@ -18,20 +18,6 @@ namespace IcePatch { -class InfoI : public Info -{ -public: - - InfoI(const Ice::ObjectAdapterPtr&); - - Ice::Long getStamp(const Ice::Current&) const; - -private: - - const Ice::ObjectAdapterPtr _adapter; - const IceUtil::Time _busyTimeout; -}; - class FileI : virtual public File { public: @@ -40,6 +26,8 @@ public: protected: + Ice::ByteSeq readMD5(const Ice::Current&) const; + const Ice::ObjectAdapterPtr _adapter; const Ice::LoggerPtr _logger; const Ice::Int _traceLevel; diff --git a/cpp/src/IcePatch/Server.cpp b/cpp/src/IcePatch/Server.cpp index 8f83ba69a04..bb7029dfec7 100644 --- a/cpp/src/IcePatch/Server.cpp +++ b/cpp/src/IcePatch/Server.cpp @@ -128,12 +128,6 @@ IcePatch::Server::run(int argc, char* argv[]) adapter->addServantLocator(fileLocator, "IcePatch"); // - // Create the "info" Ice Object. - // - InfoPtr info = new InfoI(adapter); - adapter->add(info, pathToIdentity(".icepatch")); // .icepatch is reserved, so lets use this for info identity. - - // // Start the updater if an update period is set. // UpdaterPtr updater; @@ -255,6 +249,13 @@ IcePatch::Updater::cleanup(const FileDescSeq& fileDescSeq) // removed. // cleanup(directoryDesc->directory->getContents()); + + // + // Call describe(), because MD5 files in subdirectories + // might have changed, resulting in a different summary + // MD5 for this directory. + // + directoryDesc->directory->describe(); } else { @@ -262,7 +263,7 @@ IcePatch::Updater::cleanup(const FileDescSeq& fileDescSeq) assert(regularDesc); // - // Force BZ2 files to be created. + // Force BZ2 files to be created for all regular files. // regularDesc->regular->getBZ2Size(); } diff --git a/cpp/src/IcePatch/Util.cpp b/cpp/src/IcePatch/Util.cpp index 2906620819f..42b1d419042 100644 --- a/cpp/src/IcePatch/Util.cpp +++ b/cpp/src/IcePatch/Util.cpp @@ -324,46 +324,66 @@ IcePatch::getMD5(const string& path) void IcePatch::createMD5(const string& path) { - FileInfo info = getFileInfo(path, true); - if(info.type == FileTypeDirectory) - { - FileAccessException ex; - ex.reason = "cannot create MD5 file for `" + path + "' because this is a directory"; - throw ex; - } - // - // Read the original file. + // The current directory is not permissible for MD5 value + // creation. // - ifstream file(path.c_str(), ios::binary); - if(!file) + assert(path != "."); + + ByteSeq bytes; + + FileInfo info = getFileInfo(path, true); + if(info.type == FileTypeDirectory) { - FileAccessException ex; - ex.reason = "cannot open `" + path + "' for reading: " + strerror(errno); - throw ex; + // + // Create a summary of all MD5 files. + // + StringSeq paths = readDirectory(path); + for(StringSeq::const_iterator p = paths.begin(); p < paths.end(); ++p) + { + if(getSuffix(*p) == "md5") + { + ByteSeq subBytesMD5 = getMD5(removeSuffix(*p)); + copy(subBytesMD5.begin(), subBytesMD5.end(), back_inserter(bytes)); + } + } } - - ByteSeq bytes; - bytes.resize(info.size); - if(bytes.size() > 0) + else { - file.read(&bytes[0], bytes.size()); + assert(info.type == FileTypeRegular); + + // + // Read the original file. + // + ifstream file(path.c_str(), ios::binary); if(!file) { FileAccessException ex; - ex.reason = "cannot read `" + path + "': " + strerror(errno); + ex.reason = "cannot open `" + path + "' for reading: " + strerror(errno); throw ex; } - if(file.gcount() < static_cast<int>(bytes.size())) + + bytes.resize(info.size); + if(bytes.size() > 0) { - FileAccessException ex; - ex.reason = "could not read all bytes from `" + path + "'"; - throw ex; + 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(); } - file.close(); - // // Create the MD5 hash value. // @@ -652,85 +672,3 @@ IcePatch::createBZ2(const string& path) throw ex; } } - -Long -IcePatch::readStamp() -{ - ifstream fileStamp(".icepatch/stamp"); - if(!fileStamp) // Ignore any errors if the file cannot be read. - { - return -1; - } - - string s; - fileStamp >> s; - fileStamp.close(); - - Long stamp; - string::size_type dummy; - if(!IceUtil::stringToInt64(s, stamp, dummy)) // Ignore errors during conversion. - { - return -1; - } - - return stamp; -} - -void -IcePatch::writeStamp(Long stamp) -{ - ofstream fileStamp(".icepatch/stamp"); - if(!fileStamp) - { - // - // Prepare an exception, but don't throw yet. - // - FileAccessException ex; - ex.reason = string("cannot open `.icepatch/stamp' for writing: ") + strerror(errno); - - // - // Check if the directory exists, and only throw the exception - // if it does exist. Otherwise create the directory, and try - // again. - // - FileInfo info = getFileInfo(".icepatch", false); - if(info.type == FileTypeDirectory) - { - // - // If the directory exists, throw the exception. - // - throw ex; - } - else - { - // - // If the directory does not exist, create it, and try - // again. - // - if(info.type != FileTypeNotExist) - { - removeRecursive(".icepatch"); - } - - createDirectory(".icepatch"); - - ofstream fileStamp(".icepatch/stamp"); - if(!fileStamp) - { - FileAccessException ex; - ex.reason = string("cannot open `.icepatch/stamp' for writing: ") + strerror(errno); - throw ex; - } - else - { - fileStamp << stamp << endl; - fileStamp.close(); - } - } - } - else - { - fileStamp << stamp << endl; - fileStamp.close(); - } -} |