summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/IcePatch/Client.cpp84
-rw-r--r--cpp/src/IcePatch/Util.cpp28
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