Browse Source

fix problems patching

David Rose 23 years ago
parent
commit
67d32fc172

+ 6 - 0
panda/src/express/config_express.cxx

@@ -149,6 +149,12 @@ const int patchfile_buffer_size =
 const int patchfile_zone_size =
 const int patchfile_zone_size =
         config_express.GetInt("patchfile-zone-size", 10000);
         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
 // Set this true to use the VirtualFileSystem mechanism for loading
 // models, etc.  Since the VirtualFileSystem maps to the same as the
 // models, etc.  Since the VirtualFileSystem maps to the same as the
 // actual file system by default, there is probably no reason to set
 // actual file system by default, there is probably no reason to set

+ 2 - 0
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_buffer_size;
 extern const int patchfile_zone_size;
 extern const int patchfile_zone_size;
 
 
+extern const bool keep_temporary_files;
+
 extern EXPCL_PANDAEXPRESS const bool use_vfs;
 extern EXPCL_PANDAEXPRESS const bool use_vfs;
 
 
 // Expose the Config variable for Python access.
 // Expose the Config variable for Python access.

+ 10 - 0
panda/src/express/hashVal.I

@@ -41,6 +41,16 @@ operator == (const HashVal &other) const {
           hv[3] == other.hv[3]);
           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
 //     Function: HashVal::get_value
 //       Access: Public
 //       Access: Public

+ 1 - 0
panda/src/express/hashVal.h

@@ -31,6 +31,7 @@ class EXPCL_PANDAEXPRESS HashVal {
 PUBLISHED:
 PUBLISHED:
   INLINE HashVal();
   INLINE HashVal();
   INLINE bool operator == (const HashVal &other) const;
   INLINE bool operator == (const HashVal &other) const;
+  INLINE bool operator != (const HashVal &other) const;
   INLINE uint get_value(int val) const;
   INLINE uint get_value(int val) const;
   INLINE void set_value(int val, uint hash);
   INLINE void set_value(int val, uint hash);
   INLINE void output(ostream &out) const;
   INLINE void output(ostream &out) const;

+ 73 - 67
panda/src/express/patchfile.cxx

@@ -18,10 +18,12 @@
 
 
 #include "config_express.h"
 #include "config_express.h"
 #include "error_utils.h"
 #include "error_utils.h"
-#include <stdio.h> // for tempnam
-
 #include "patchfile.h"
 #include "patchfile.h"
 #include "crypto_utils.h" // MD5 stuff
 #include "crypto_utils.h" // MD5 stuff
+#include "streamReader.h"
+#include "streamWriter.h"
+
+#include <stdio.h> // for tempnam
 
 
 // PROFILING ///////////////////////////////////////////////////////
 // PROFILING ///////////////////////////////////////////////////////
 //#define PROFILE_PATCH_BUILD
 //#define PROFILE_PATCH_BUILD
@@ -108,8 +110,6 @@ init(PT(Buffer) buffer) {
   _buffer = buffer;
   _buffer = buffer;
 
 
   reset_footprint_length();
   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;
         << "Patchfile::initiate() - Failed to create temp file name, using default" << endl;
       _temp_file = "patcher_temp_file";
       _temp_file = "patcher_temp_file";
     } else {
     } else {
-      //cout << tempfilename << endl;
       _temp_file = tempfilename;
       _temp_file = tempfilename;
       free(tempfilename);
       free(tempfilename);
     }
     }
   }
   }
+
   _temp_file.set_binary();
   _temp_file.set_binary();
   if (!_temp_file.open_write(_write_stream)) {
   if (!_temp_file.open_write(_write_stream)) {
     express_cat.error()
     express_cat.error()
@@ -210,16 +210,19 @@ initiate(Filename &patch_file, Filename &file) {
     return get_write_error();
     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
   // read header, make sure the patch file is valid
 
 
+  StreamReader patch_reader(_patch_stream);
+
   // check the magic number
   // check the magic number
   nassertr(_buffer->get_length() >= _header_length, false);
   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) {
   if (magic_number != _magic_number) {
     express_cat.error()
     express_cat.error()
       << "Patchfile::initiate() - invalid patch file: " << _patch_file << endl;
       << "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
   // 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
   // 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()
   express_cat.debug()
     << "Patchfile::initiate() - valid patchfile" << endl;
     << "Patchfile::initiate() - valid patchfile" << endl;
-  /*
-  express_cat.debug()
-    << "Patchfile::initiate() - valid patchfile for file: " << name << endl;
-  */
 
 
   _total_bytes_processed = 0;
   _total_bytes_processed = 0;
 
 
@@ -270,6 +269,8 @@ run(void) {
     return EU_error_abort;
     return EU_error_abort;
   }
   }
 
 
+  StreamReader patch_reader(_patch_stream);
+
   buflen = _buffer->get_length();
   buflen = _buffer->get_length();
   bytes_read = 0;
   bytes_read = 0;
 
 
@@ -277,11 +278,7 @@ run(void) {
     ///////////
     ///////////
     // read # of ADD bytes
     // read # of ADD bytes
     nassertr(_buffer->get_length() >= (int)sizeof(ADD_length), false);
     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;
     bytes_read += (int)ADD_length;
     _total_bytes_processed += (int)ADD_length;
     _total_bytes_processed += (int)ADD_length;
@@ -290,7 +287,10 @@ run(void) {
     if (0 != ADD_length) {
     if (0 != ADD_length) {
       PN_uint32 bytes_left = (PN_uint32)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) {
       while (bytes_left > 0) {
         PN_uint32 bytes_this_time = (PN_uint32) min(bytes_left, (PN_uint32) buflen);
         PN_uint32 bytes_this_time = (PN_uint32) min(bytes_left, (PN_uint32) buflen);
@@ -303,11 +303,7 @@ run(void) {
     ///////////
     ///////////
     // read # of COPY bytes
     // read # of COPY bytes
     nassertr(_buffer->get_length() >= (int)sizeof(COPY_length), false);
     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;
     bytes_read += (int)COPY_length;
     _total_bytes_processed += (int)COPY_length;
     _total_bytes_processed += (int)COPY_length;
@@ -316,13 +312,13 @@ run(void) {
     if (0 != COPY_length) {
     if (0 != COPY_length) {
       // read copy offset
       // read copy offset
       nassertr(_buffer->get_length() >= (int)sizeof(COPY_offset), false);
       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
       // seek to the offset
       _origfile_stream.seekg(COPY_offset, ios::beg);
       _origfile_stream.seekg(COPY_offset, ios::beg);
@@ -342,24 +338,46 @@ run(void) {
     if ((0 == ADD_length) && (0 == COPY_length)) {
     if ((0 == ADD_length) && (0 == COPY_length)) {
       cleanup();
       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
       // check the MD5 from the patch file against the newly patched file
       {
       {
         HashVal MD5_actual;
         HashVal MD5_actual;
         md5_a_file(_temp_file, 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
           // 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 "invalid checksum"
           return EU_error_invalid_checksum;
           return EU_error_invalid_checksum;
         }
         }
       }
       }
 
 
       // delete the patch file and the original file
       // 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
       // rename the temp file to the original file name
       if (!_temp_file.rename_to(_orig_file)) {
       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;
   //cout << "ADD: " << length << " bytes" << endl;
 
 
   // write ADD length
   // 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 there are bytes to add, add them
   if (length > 0) {
   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;
   //cout << "COPY: " << length << " bytes at offset " << offset << endl;
 
 
   // write COPY length
   // 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) {
   if(length > 0) {
     // write COPY offset
     // 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);
   START_PROFILE(writeHeader);
 
 
   // write the patch file header
   // 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
     // calc MD5 of resultant patched file
     HashVal md5New;
     HashVal md5New;
     md5_a_buffer((const unsigned char*)buffer_new, (int)length_new, md5New);
     md5_a_buffer((const unsigned char*)buffer_new, (int)length_new, md5New);
     // add it to the header
     // 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");
   END_PROFILE(writeHeader, "writing patch file header");
 
 

+ 0 - 2
panda/src/express/patchfile.h

@@ -113,8 +113,6 @@ protected:
   Filename _orig_file;
   Filename _orig_file;
   Filename _temp_file;
   Filename _temp_file;
 
 
-  Datagram _datagram; // used to eliminate endian problems
-
   static const PN_uint32 _magic_number;
   static const PN_uint32 _magic_number;
 };
 };