diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/IcePatch/Client.cpp | 84 | ||||
-rw-r--r-- | cpp/src/IcePatch/Util.cpp | 28 |
2 files changed, 92 insertions, 20 deletions
diff --git a/cpp/src/IcePatch/Client.cpp b/cpp/src/IcePatch/Client.cpp index 7bcd89fb893..1b047ac9651 100644 --- a/cpp/src/IcePatch/Client.cpp +++ b/cpp/src/IcePatch/Client.cpp @@ -528,21 +528,21 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent) c MyProgressCB progressCB; + bool update = false; + FileInfo info = getFileInfo(path, false); switch(info.type) { case FileTypeNotExist: { - orphaned.erase(path + ".bz2"); - getRegular(regDesc->reg, progressCB); + update = true; break; } case FileTypeDirectory: { removeRecursive(path); - orphaned.erase(path + ".bz2"); - getRegular(regDesc->reg, progressCB); + update = true; break; } @@ -550,18 +550,24 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent) c { ByteSeq md5; - string pathMD5 = path + ".md5"; - FileInfo infoMD5 = getFileInfo(pathMD5, false); - if(infoMD5.type == FileTypeRegular && infoMD5.time >= info.time) + if(_thorough) { - md5 = getMD5(path); + md5 = calcMD5(path); + } + else + { + string pathMD5 = path + ".md5"; + FileInfo infoMD5 = getFileInfo(pathMD5, false); + if(infoMD5.type == FileTypeRegular && infoMD5.time >= info.time) + { + md5 = getMD5(path); + } } if(md5 != regDesc->md5) { removeRecursive(path); - orphaned.erase(path + ".bz2"); - getRegular(regDesc->reg, progressCB); + update = true; } else { @@ -571,6 +577,64 @@ IcePatch::Client::patch(const DirectoryDescPtr& dirDesc, const string& indent) c break; } } + + if(update) + { + orphaned.erase(path + ".bz2"); + + int retries = 0; + while(true) + { + // + // Retrieve file from server. + // + getRegular(regDesc->reg, progressCB); + + // + // Get the latest file description from server, as + // the file may mave recently changed. + // + regDesc = RegularDescPtr::dynamicCast(regDesc->reg->describe()); + if(!regDesc) + { + removeRecursive(path); + + FileAccessException ex; + ex.reason = "Unexpected error accessing `" + path + "' remotely."; + throw ex; + } + + // + // Compare the icepatch and locally built MD5s. If + // they differ, try again unless we've hit the + // retry limit. + // + ByteSeq md5; + string pathMD5 = path + ".md5"; + FileInfo infoMD5 = getFileInfo(pathMD5, false); + if(infoMD5.type == FileTypeRegular) + { + md5 = getMD5(path); + } + + if(regDesc->md5 == md5) + { + break; + } + else if(retries < 3) + { + ++retries; + } + else + { + removeRecursive(path); + + FileAccessException ex; + ex.reason = "Error patching `" + path + "'."; + throw ex; + } + } + } } } diff --git a/cpp/src/IcePatch/Util.cpp b/cpp/src/IcePatch/Util.cpp index 79950e4a19d..1ee749b8e0d 100644 --- a/cpp/src/IcePatch/Util.cpp +++ b/cpp/src/IcePatch/Util.cpp @@ -532,6 +532,23 @@ IcePatch::createMD5(const string& path, const LoggerPtr& logger) // assert(path != "."); + // + // Calculate and save the MD5 hash value. + // + ByteSeq bytesMD5 = calcMD5(path, logger); + + putMD5(path, bytesMD5); + + if(logger) + { + Trace out(logger, "IcePatch"); + out << "created MD5 file for `" << path << "'"; + } +} + +ByteSeq +IcePatch::calcMD5(const string& path, const LoggerPtr& logger) +{ ByteSeq bytes; FileInfo info = getFileInfo(path, true, logger); @@ -608,16 +625,7 @@ IcePatch::createMD5(const string& path, const LoggerPtr& logger) fill(bytesMD5.begin(), bytesMD5.end(), 0); } - // - // Save the MD5 hash value. - // - putMD5(path, bytesMD5); - - if(logger) - { - Trace out(logger, "IcePatch"); - out << "created MD5 file for `" << path << "'"; - } + return bytesMD5; } ByteSeq |