From 67d32fc1729290a0a803c8e81a90910a112c04cf Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 29 Oct 2002 00:38:44 +0000 Subject: [PATCH] fix problems patching --- panda/src/express/config_express.cxx | 6 ++ panda/src/express/config_express.h | 2 + panda/src/express/hashVal.I | 10 ++ panda/src/express/hashVal.h | 1 + panda/src/express/patchfile.cxx | 140 ++++++++++++++------------- panda/src/express/patchfile.h | 2 - 6 files changed, 92 insertions(+), 69 deletions(-) diff --git a/panda/src/express/config_express.cxx b/panda/src/express/config_express.cxx index 5380ba0b24..f8d93f10d3 100644 --- a/panda/src/express/config_express.cxx +++ b/panda/src/express/config_express.cxx @@ -149,6 +149,12 @@ const int patchfile_buffer_size = const int patchfile_zone_size = config_express.GetInt("patchfile-zone-size", 10000); +// Set this true to keep around the temporary files from downloading, +// decompressing, and patching, or false (the default) to delete +// these. Mainly useful for debugging when the process goes wrong. +const bool keep_temporary_files = +config_express.GetBool("keep-temporary-files", false); + // Set this true to use the VirtualFileSystem mechanism for loading // models, etc. Since the VirtualFileSystem maps to the same as the // actual file system by default, there is probably no reason to set diff --git a/panda/src/express/config_express.h b/panda/src/express/config_express.h index 838e8e9788..dec1d20fc1 100644 --- a/panda/src/express/config_express.h +++ b/panda/src/express/config_express.h @@ -46,6 +46,8 @@ extern const int patchfile_increment_size; extern const int patchfile_buffer_size; extern const int patchfile_zone_size; +extern const bool keep_temporary_files; + extern EXPCL_PANDAEXPRESS const bool use_vfs; // Expose the Config variable for Python access. diff --git a/panda/src/express/hashVal.I b/panda/src/express/hashVal.I index f18724c51b..39b8019b3e 100644 --- a/panda/src/express/hashVal.I +++ b/panda/src/express/hashVal.I @@ -41,6 +41,16 @@ operator == (const HashVal &other) const { hv[3] == other.hv[3]); } +//////////////////////////////////////////////////////////////////// +// Function: HashVal::operator != +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool HashVal:: +operator != (const HashVal &other) const { + return !operator == (other); +} + //////////////////////////////////////////////////////////////////// // Function: HashVal::get_value // Access: Public diff --git a/panda/src/express/hashVal.h b/panda/src/express/hashVal.h index 433e80b0eb..cd508f5e0c 100644 --- a/panda/src/express/hashVal.h +++ b/panda/src/express/hashVal.h @@ -31,6 +31,7 @@ class EXPCL_PANDAEXPRESS HashVal { PUBLISHED: INLINE HashVal(); INLINE bool operator == (const HashVal &other) const; + INLINE bool operator != (const HashVal &other) const; INLINE uint get_value(int val) const; INLINE void set_value(int val, uint hash); INLINE void output(ostream &out) const; diff --git a/panda/src/express/patchfile.cxx b/panda/src/express/patchfile.cxx index 4e18e378d2..d68b45ac27 100644 --- a/panda/src/express/patchfile.cxx +++ b/panda/src/express/patchfile.cxx @@ -18,10 +18,12 @@ #include "config_express.h" #include "error_utils.h" -#include // for tempnam - #include "patchfile.h" #include "crypto_utils.h" // MD5 stuff +#include "streamReader.h" +#include "streamWriter.h" + +#include // for tempnam // PROFILING /////////////////////////////////////////////////////// //#define PROFILE_PATCH_BUILD @@ -108,8 +110,6 @@ init(PT(Buffer) buffer) { _buffer = buffer; reset_footprint_length(); - - _datagram.clear(); } //////////////////////////////////////////////////////////////////// @@ -198,11 +198,11 @@ initiate(Filename &patch_file, Filename &file) { << "Patchfile::initiate() - Failed to create temp file name, using default" << endl; _temp_file = "patcher_temp_file"; } else { - //cout << tempfilename << endl; _temp_file = tempfilename; free(tempfilename); } } + _temp_file.set_binary(); if (!_temp_file.open_write(_write_stream)) { express_cat.error() @@ -210,16 +210,19 @@ initiate(Filename &patch_file, Filename &file) { return get_write_error(); } + if (express_cat.is_debug()) { + express_cat.debug() + << "Using temporary file " << _temp_file << "\n"; + } + ///////////// // read header, make sure the patch file is valid + StreamReader patch_reader(_patch_stream); + // check the magic number nassertr(_buffer->get_length() >= _header_length, false); - _patch_stream.read(_buffer->_buffer, _header_length); - _datagram.clear(); - _datagram.append_data(_buffer->_buffer, _header_length); - DatagramIterator di(_datagram); - PN_uint32 magic_number = di.get_uint32(); + PN_uint32 magic_number = patch_reader.get_uint32(); if (magic_number != _magic_number) { express_cat.error() << "Patchfile::initiate() - invalid patch file: " << _patch_file << endl; @@ -227,20 +230,16 @@ initiate(Filename &patch_file, Filename &file) { } // get the length of the patched result file - _result_file_length = di.get_uint32(); + _result_file_length = patch_reader.get_uint32(); // get the MD5 of the resultant patched file - _MD5_ofResult.set_value(0, di.get_uint32()); - _MD5_ofResult.set_value(1, di.get_uint32()); - _MD5_ofResult.set_value(2, di.get_uint32()); - _MD5_ofResult.set_value(3, di.get_uint32()); + _MD5_ofResult.set_value(0, patch_reader.get_uint32()); + _MD5_ofResult.set_value(1, patch_reader.get_uint32()); + _MD5_ofResult.set_value(2, patch_reader.get_uint32()); + _MD5_ofResult.set_value(3, patch_reader.get_uint32()); express_cat.debug() << "Patchfile::initiate() - valid patchfile" << endl; - /* - express_cat.debug() - << "Patchfile::initiate() - valid patchfile for file: " << name << endl; - */ _total_bytes_processed = 0; @@ -270,6 +269,8 @@ run(void) { return EU_error_abort; } + StreamReader patch_reader(_patch_stream); + buflen = _buffer->get_length(); bytes_read = 0; @@ -277,11 +278,7 @@ run(void) { /////////// // read # of ADD bytes nassertr(_buffer->get_length() >= (int)sizeof(ADD_length), false); - _patch_stream.read(_buffer->_buffer, sizeof(ADD_length)); - _datagram.clear(); - _datagram.append_data(_buffer->_buffer, sizeof(ADD_length)); - DatagramIterator di(_datagram); - ADD_length = di.get_uint16(); + ADD_length = patch_reader.get_uint16(); bytes_read += (int)ADD_length; _total_bytes_processed += (int)ADD_length; @@ -290,7 +287,10 @@ run(void) { if (0 != ADD_length) { PN_uint32 bytes_left = (PN_uint32)ADD_length; - //cout << "ADD: " << ADD_length << endl; + if (express_cat.is_spam()) { + express_cat.spam() + << "ADD: " << ADD_length << endl; + } while (bytes_left > 0) { PN_uint32 bytes_this_time = (PN_uint32) min(bytes_left, (PN_uint32) buflen); @@ -303,11 +303,7 @@ run(void) { /////////// // read # of COPY bytes nassertr(_buffer->get_length() >= (int)sizeof(COPY_length), false); - _patch_stream.read(_buffer->_buffer, sizeof(COPY_length)); - _datagram.clear(); - _datagram.append_data(_buffer->_buffer, sizeof(COPY_length)); - DatagramIterator di2(_datagram); - COPY_length = di2.get_uint16(); + COPY_length = patch_reader.get_uint16(); bytes_read += (int)COPY_length; _total_bytes_processed += (int)COPY_length; @@ -316,13 +312,13 @@ run(void) { if (0 != COPY_length) { // read copy offset nassertr(_buffer->get_length() >= (int)sizeof(COPY_offset), false); - _patch_stream.read(_buffer->_buffer, sizeof(COPY_offset)); - _datagram.clear(); - _datagram.append_data(_buffer->_buffer, sizeof(COPY_offset)); - DatagramIterator di(_datagram); - COPY_offset = di.get_uint32(); + COPY_offset = patch_reader.get_uint32(); - //cout << "COPY: " << COPY_length << " bytes at offset " << COPY_offset << endl; + if (express_cat.is_spam()) { + express_cat.spam() + << "COPY: " << COPY_length << " bytes at offset " << COPY_offset + << endl; + } // seek to the offset _origfile_stream.seekg(COPY_offset, ios::beg); @@ -342,24 +338,46 @@ run(void) { if ((0 == ADD_length) && (0 == COPY_length)) { cleanup(); - //cout << _result_file_length << " " << _total_bytes_processed << endl; + if (express_cat.is_spam()) { + express_cat.spam() + << "result file = " << _result_file_length + << " total bytes = " << _total_bytes_processed << endl; + } // check the MD5 from the patch file against the newly patched file { HashVal MD5_actual; md5_a_file(_temp_file, MD5_actual); - if (memcmp((const void*)&_MD5_ofResult, (const void*)&MD5_actual, sizeof(HashVal))) { + if (_MD5_ofResult != MD5_actual) { + express_cat.info() + << "Patching produced incorrect checksum. Got:\n" + << " " << MD5_actual + << "\nExpected:\n" + << " " << _MD5_ofResult + << "\n"; + // delete the temp file and the patch file - _temp_file.unlink(); - _patch_file.unlink(); + if (!keep_temporary_files) { + _temp_file.unlink(); + _patch_file.unlink(); + } // return "invalid checksum" return EU_error_invalid_checksum; } } // delete the patch file and the original file - _patch_file.unlink(); - _orig_file.unlink(); + if (!keep_temporary_files) { + _patch_file.unlink(); + _orig_file.unlink(); + + } else { + // If we're keeping temporary files, rename the orig file to a + // backup. + Filename orig_backup = _orig_file.get_fullpath() + ".orig"; + orig_backup.unlink(); + _orig_file.rename_to(orig_backup); + } // rename the temp file to the original file name if (!_temp_file.rename_to(_orig_file)) { @@ -618,17 +636,12 @@ emit_ADD(ofstream &write_stream, PN_uint16 length, const char* buffer) { //cout << "ADD: " << length << " bytes" << endl; // write ADD length - _datagram.clear(); - _datagram.add_uint16(length); - string msg = _datagram.get_message(); - write_stream.write((char *)msg.data(), msg.length()); + StreamWriter patch_writer(write_stream); + patch_writer.add_uint16(length); // if there are bytes to add, add them if (length > 0) { - _datagram.clear(); - _datagram.append_data(buffer, length); - string msg = _datagram.get_message(); - write_stream.write((char *)msg.data(), msg.length()); + patch_writer.append_data(buffer, length); } } @@ -642,17 +655,12 @@ emit_COPY(ofstream &write_stream, PN_uint16 length, PN_uint32 offset) { //cout << "COPY: " << length << " bytes at offset " << offset << endl; // write COPY length - _datagram.clear(); - _datagram.add_uint16(length); - string msg = _datagram.get_message(); - write_stream.write((char *)msg.data(), msg.length()); + StreamWriter patch_writer(write_stream); + patch_writer.add_uint16(length); if(length > 0) { // write COPY offset - _datagram.clear(); - _datagram.add_uint32(offset); - string msg2 = _datagram.get_message(); - write_stream.write((char *)msg2.data(), msg2.length()); + patch_writer.add_uint32(offset); } } @@ -744,21 +752,19 @@ build(Filename &file_orig, Filename &file_new) { START_PROFILE(writeHeader); // write the patch file header - _datagram.clear(); - _datagram.add_uint32(_magic_number); - _datagram.add_uint32(length_new); + StreamWriter patch_writer(write_stream); + patch_writer.add_uint32(_magic_number); + patch_writer.add_uint32(length_new); { // calc MD5 of resultant patched file HashVal md5New; md5_a_buffer((const unsigned char*)buffer_new, (int)length_new, md5New); // add it to the header - _datagram.add_uint32(md5New.get_value(0)); - _datagram.add_uint32(md5New.get_value(1)); - _datagram.add_uint32(md5New.get_value(2)); - _datagram.add_uint32(md5New.get_value(3)); + patch_writer.add_uint32(md5New.get_value(0)); + patch_writer.add_uint32(md5New.get_value(1)); + patch_writer.add_uint32(md5New.get_value(2)); + patch_writer.add_uint32(md5New.get_value(3)); } - string msg = _datagram.get_message(); - write_stream.write((char *)msg.data(), msg.length()); END_PROFILE(writeHeader, "writing patch file header"); diff --git a/panda/src/express/patchfile.h b/panda/src/express/patchfile.h index 4768f98320..44d03a1918 100644 --- a/panda/src/express/patchfile.h +++ b/panda/src/express/patchfile.h @@ -113,8 +113,6 @@ protected: Filename _orig_file; Filename _temp_file; - Datagram _datagram; // used to eliminate endian problems - static const PN_uint32 _magic_number; };