diff options
author | Marc Laukien <marc@zeroc.com> | 2002-04-05 03:45:23 +0000 |
---|---|---|
committer | Marc Laukien <marc@zeroc.com> | 2002-04-05 03:45:23 +0000 |
commit | c92972c738d538caca10fe31921d577c1f70ea4f (patch) | |
tree | de87b66756095437699460c062a4f8f91ab6a239 /cpp/src/IcePatch/Util.cpp | |
parent | more IcePatch stuff (diff) | |
download | ice-c92972c738d538caca10fe31921d577c1f70ea4f.tar.bz2 ice-c92972c738d538caca10fe31921d577c1f70ea4f.tar.xz ice-c92972c738d538caca10fe31921d577c1f70ea4f.zip |
more IcePatch stuff
Diffstat (limited to 'cpp/src/IcePatch/Util.cpp')
-rw-r--r-- | cpp/src/IcePatch/Util.cpp | 290 |
1 files changed, 195 insertions, 95 deletions
diff --git a/cpp/src/IcePatch/Util.cpp b/cpp/src/IcePatch/Util.cpp index 957133e139b..63da8e356ee 100644 --- a/cpp/src/IcePatch/Util.cpp +++ b/cpp/src/IcePatch/Util.cpp @@ -22,6 +22,8 @@ using namespace std; using namespace Ice; using namespace IcePatch; +const string IcePatch::tmpName = ".icepatchtmp"; + static string normalizePath(const string& path) { @@ -193,6 +195,46 @@ IcePatch::createDirectory(const string& path) ByteSeq IcePatch::getMD5(const string& path) { + string pathMD5 = path + ".md5"; + ifstream fileMD5(pathMD5.c_str()); + if (!fileMD5) + { + NodeAccessException ex; + ex.reason = "cannot open `" + pathMD5 + "' for reading:" + strerror(errno); + throw ex; + } + ByteSeq bytesMD5; + bytesMD5.resize(16); + fileMD5.read(&bytesMD5[0], 16); + if (!fileMD5) + { + NodeAccessException ex; + ex.reason = "cannot read `" + pathMD5 + "':" + strerror(errno); + throw ex; + } + if (fileMD5.gcount() < 16) + { + NodeAccessException ex; + ex.reason = "could not read 16 bytes from `" + pathMD5 + "'"; + throw ex; + } + return bytesMD5; +} + +void +IcePatch::createMD5(const string& path) +{ + if (pathToName(path) == tmpName) + { + return; + } + + string suffix = getSuffix(path); + if (suffix == "md5" || suffix == "bz2") + { + return; + } + // // Stat the file to get a MD5 hash value for. // @@ -219,12 +261,12 @@ IcePatch::getMD5(const string& path) // struct stat bufMD5; string pathMD5 = path + ".md5"; - bool createMD5 = false; + bool makeMD5 = false; if (::stat(pathMD5.c_str(), &bufMD5) == -1) { if (errno == ENOENT) { - createMD5 = true; + makeMD5 = true; } else { @@ -238,27 +280,24 @@ IcePatch::getMD5(const string& path) if (!S_ISREG(bufMD5.st_mode)) { NodeAccessException ex; - ex.reason = "`" + path + "' is not a regular file"; + ex.reason = "`" + pathMD5 + "' is not a regular file"; throw ex; } if (bufMD5.st_size != 16) { NodeAccessException ex; - ex.reason = "`" + path + "' isn't 16 bytes in size"; + ex.reason = "`" + pathMD5 + "' isn't 16 bytes in size"; throw ex; } if (bufMD5.st_mtime <= buf.st_mtime) { - createMD5 = true; + makeMD5 = true; } } - ByteSeq bytesMD5; - bytesMD5.resize(16); - - if (createMD5) + if (makeMD5) { // // Read the original file. @@ -290,79 +329,61 @@ IcePatch::getMD5(const string& path) // // 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 the MD5 file. // - ofstream fileMD5(pathMD5.c_str()); + ofstream fileMD5(tmpName.c_str()); if (!fileMD5) { NodeAccessException ex; - ex.reason = "cannot open `" + pathMD5 + "' for writing:" + strerror(errno); + ex.reason = "cannot open `" + tmpName + "' for writing:" + strerror(errno); throw ex; } fileMD5.write(&bytesMD5[0], 16); if (!fileMD5) { NodeAccessException ex; - ex.reason = "cannot write `" + pathMD5 + "':" + strerror(errno); + ex.reason = "cannot write `" + tmpName + "':" + strerror(errno); throw ex; } fileMD5.close(); - } - else - { + // - // Read the MD5 hash value from the MD5 file. + // Rename the temporary MD5 file to the "real" MD5 file. This + // is done so that there can be no partial MD5 files after an + // abortive application termination. // - ifstream fileMD5(pathMD5.c_str()); - if (!fileMD5) - { - NodeAccessException ex; - ex.reason = "cannot open `" + pathMD5 + "' for reading:" + strerror(errno); - throw ex; - } - fileMD5.read(&bytesMD5[0], 16); - if (!fileMD5) - { - NodeAccessException ex; - ex.reason = "cannot read `" + pathMD5 + "':" + strerror(errno); - throw ex; - } - if (fileMD5.gcount() < 16) + if (rename(tmpName.c_str(), pathMD5.c_str()) == -1) { NodeAccessException ex; - ex.reason = "could not read 16 bytes from `" + pathMD5 + "'"; + ex.reason = "cannot rename `" + tmpName + "' to `" + pathMD5 + "':" + strerror(errno); throw ex; } - fileMD5.close(); } - - return bytesMD5; } -string -IcePatch::MD5ToString(const ByteSeq& bytesMD5) +void +IcePatch::createMD5Recursive(const string& path) { - if (bytesMD5.size() != 16) - { - return "illegal MD5 hash code"; - } - - ostringstream out; + FileInfo info = getFileInfo(path); - for (int i = 0; i < 16; ++i) + if (info == FileInfoDirectory) { - int b = static_cast<int>(bytesMD5[i]); - if (b < 0) + StringSeq paths = readDirectory(path); + StringSeq::const_iterator p; + for (p = paths.begin(); p != paths.end(); ++p) { - b += 256; + createMD5Recursive(*p); } - out << hex << b; } - - return out.str(); + else if (info == FileInfoRegular) + { + createMD5(path); + } } void @@ -375,6 +396,12 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes) ex.reason = "cannot open `" + pathBZ2 + "' for writing:" + strerror(errno); throw ex; } + + if (bytes.empty()) + { + fclose(file); + return; + } try { @@ -384,6 +411,10 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes) { NodeAccessException ex; ex.reason = "BZ2_bzWriteOpen failed"; + if (bzError == BZ_IO_ERROR) + { + ex.reason += string(": ") + strerror(errno); + } throw ex; } @@ -394,6 +425,10 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes) { NodeAccessException ex; ex.reason = "BZ2_bzWrite failed"; + if (bzError == BZ_IO_ERROR) + { + ex.reason += string(": ") + strerror(errno); + } throw ex; } @@ -402,6 +437,10 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes) { NodeAccessException ex; ex.reason = "BZ2_bzWriteClose failed"; + if (bzError == BZ_IO_ERROR) + { + ex.reason += string(": ") + strerror(errno); + } throw ex; } } @@ -412,6 +451,10 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes) { NodeAccessException ex; ex.reason = "BZ2_bzWriteClose failed"; + if (bzError == BZ_IO_ERROR) + { + ex.reason += string(": ") + strerror(errno); + } throw ex; } throw; @@ -426,9 +469,67 @@ IcePatch::writeBZ2(const string& pathBZ2, const ByteSeq& bytes) } } +Int +IcePatch::getSizeBZ2(const string& path) +{ + struct stat bufBZ2; + string pathBZ2 = path + ".bz2"; + if (::stat(pathBZ2.c_str(), &bufBZ2) == -1) + { + NodeAccessException ex; + ex.reason = "cannot stat `" + path + "':" + strerror(errno); + throw ex; + } + return bufBZ2.st_size; +} + ByteSeq IcePatch::getBytesBZ2(const string& path, Int pos, Int num) { + string pathBZ2 = path + ".bz2"; + ifstream fileBZ2(pathBZ2.c_str()); + if (!fileBZ2) + { + NodeAccessException ex; + ex.reason = "cannot open `" + pathBZ2 + "' for reading:" + strerror(errno); + throw ex; + } + fileBZ2.seekg(pos); + if (!fileBZ2) + { + NodeAccessException 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()) + { + NodeAccessException ex; + ex.reason = "cannot read `" + pathBZ2 + "':" + strerror(errno); + throw ex; + } + bytesBZ2.resize(fileBZ2.gcount()); + return bytesBZ2; +} + +void +IcePatch::createBZ2(const string& path) +{ + if (pathToName(path) == tmpName) + { + return; + } + + string suffix = getSuffix(path); + if (suffix == "md5" || suffix == "bz2") + { + return; + } + // // Stat the file to get a BZ2 file for. // @@ -455,12 +556,12 @@ IcePatch::getBytesBZ2(const string& path, Int pos, Int num) // struct stat bufBZ2; string pathBZ2 = path + ".bz2"; - bool createBZ2 = false; + bool makeBZ2 = false; if (::stat(pathBZ2.c_str(), &bufBZ2) == -1) { if (errno == ENOENT) { - createBZ2 = true; + makeBZ2 = true; } else { @@ -474,17 +575,17 @@ IcePatch::getBytesBZ2(const string& path, Int pos, Int num) if (!S_ISREG(bufBZ2.st_mode)) { NodeAccessException ex; - ex.reason = "`" + path + "' is not a regular file"; + ex.reason = "`" + pathBZ2 + "' is not a regular file"; throw ex; } if (bufBZ2.st_mtime <= buf.st_mtime) { - createBZ2 = true; + makeBZ2 = true; } } - if (createBZ2) + if (makeBZ2) { // // Read the original file. @@ -514,63 +615,52 @@ IcePatch::getBytesBZ2(const string& path, Int pos, Int num) file.close(); // - // Create the BZ2 file. + // Write the BZ2 file. // - writeBZ2(pathBZ2, bytes); + writeBZ2(tmpName, bytes); -/* // - // Stat the BZ2 file. This time, the BZ2 file must exist, - // otherwise it's an error. + // Rename the temporary BZ2 file to the "real" BZ2 file. This + // is done so that there can be no partial BZ2 files after an + // abortive application termination. // - if (::stat(pathBZ2.c_str(), &bufBZ2) == -1) + if (rename(tmpName.c_str(), pathBZ2.c_str()) == -1) { NodeAccessException ex; - ex.reason = "cannot stat `" + path + "':" + strerror(errno); + ex.reason = "cannot rename `" + tmpName + "' to `" + pathBZ2 + "':" + strerror(errno); throw ex; } -*/ } +} - // - // Read the BZ2 file. - // - ifstream fileBZ2(pathBZ2.c_str()); - if (!fileBZ2) - { - NodeAccessException ex; - ex.reason = "cannot open `" + pathBZ2 + "' for reading:" + strerror(errno); - throw ex; - } - fileBZ2.seekg(pos); - if (!fileBZ2) +void +IcePatch::createBZ2Recursive(const string& path) +{ + FileInfo info = getFileInfo(path); + + if (info == FileInfoDirectory) { - NodeAccessException ex; - ostringstream out; - out << "cannot seek position " << pos << " in file `" << path << "':" << strerror(errno); - ex.reason = out.str(); - throw ex; + StringSeq paths = readDirectory(path); + StringSeq::const_iterator p; + for (p = paths.begin(); p != paths.end(); ++p) + { + createBZ2Recursive(*p); + } } - ByteSeq bytesBZ2; - bytesBZ2.resize(num); - fileBZ2.read(&bytesBZ2[0], bytesBZ2.size()); - if (!fileBZ2 && !fileBZ2.eof()) + else if (info == FileInfoRegular) { - NodeAccessException ex; - ex.reason = "cannot read `" + pathBZ2 + "':" + strerror(errno); - throw ex; + createBZ2(path); } - bytesBZ2.resize(fileBZ2.gcount()); - fileBZ2.close(); - - return bytesBZ2; } void -IcePatch::getFile(const FilePrx& file) +IcePatch::getFile(const FilePrx& file, ProgressCB& progressCB) { string path = identityToPath(file->ice_getIdentity()); + Int totalBZ2 = file->getSizeBZ2(); + progressCB.start(totalBZ2); + string pathBZ2 = path + ".bz2"; ofstream fileBZ2(pathBZ2.c_str()); if (!fileBZ2) @@ -581,9 +671,11 @@ IcePatch::getFile(const FilePrx& file) } ByteSeq bytesBZ2; Int pos = 0; - while(true) + while(pos < totalBZ2) { - bytesBZ2 = file->getBytesBZ2(pos, 256 * 1024); + static const Int num = 64 * 1024; + + bytesBZ2 = file->getBytesBZ2(pos, num); if (bytesBZ2.empty()) { break; @@ -598,6 +690,14 @@ IcePatch::getFile(const FilePrx& file) ex.reason = "cannot write `" + pathBZ2 + "':" + strerror(errno); throw ex; } + + if (static_cast<Int>(bytesBZ2.size()) < num) + { + break; + } + + progressCB.update(totalBZ2, pos); } - fileBZ2.close(); + + progressCB.finished(totalBZ2); } |