Forráskód Böngészése

* Fix problem of upgrading with uninitialized binaries causing corruption

This will not take effect until the next upgrade (to 1.3) as this is
only checked when running .upgrade when on the fixed version.
Bryan Drewery 17 éve
szülő
commit
14f34ecafb
5 módosított fájl, 46 hozzáadás és 6 törlés
  1. 2 0
      doc/UPDATES
  2. 29 3
      src/binary.c
  3. 3 1
      src/binary.h
  4. 10 1
      src/misc.c
  5. 2 1
      src/settings.h

+ 2 - 0
doc/UPDATES

@@ -1,3 +1,5 @@
+* Fix problem of upgrading with uninitialized binaries causing corruption (will kick in on future upgrades)
+
 1.2.17 - http://wraith.botpack.net/milestone/1.2.17
 * Binary pass prompt has been changed to be more clear.
 * Fix uname checking on NetBSD and OpenBSD

+ 29 - 3
src/binary.c

@@ -566,7 +566,7 @@ check_sum(const char *fname, const char *cfgfile, bool read_stdin)
   }
 }
 
-static bool check_bin_initialized(const char *fname)
+bool check_bin_initialized(const char *fname)
 {
   int i = 0;
   size_t len = strlen(shell_escape(fname)) + 3 + 1;
@@ -582,12 +582,38 @@ static bool check_bin_initialized(const char *fname)
   return 0;
 }
 
-void write_settings(const char *fname, int die, bool doconf)
+bool check_bin_compat(const char *fname)
+{
+  int i = 0;
+  size_t len = strlen(shell_escape(fname)) + 3 + 1;
+  char *path = (char *) my_calloc(1, len);
+
+  char *out = NULL;
+
+  simple_snprintf(path, len, STR("%s -3"), shell_escape(fname));
+  if (shell_exec(path, NULL, &out, NULL)) {
+    if (out) {
+      char *buf = out;
+      size_t settings_ver = atoi(newsplit(&buf)), settings_len = atoi(newsplit(&buf));
+      if (settings_ver == SETTINGS_VER && settings_len == sizeof(settings_t)) {
+        free(path);
+        free(out);
+        return 1;
+      }
+      free(out);
+    }
+  }
+  free(path);
+  return 0;
+}
+
+void write_settings(const char *fname, int die, bool doconf, int initialized)
 {
   char *hash = NULL;
   int bits = WRITE_CHECKSUM;
   /* see if the binary is already initialized or not */
-  bool initialized = check_bin_initialized(fname);
+  if (initialized == -1)
+    initialized = check_bin_initialized(fname);
 
   /* only write pack data if the binary is uninitialized
    * otherwise, assume it has similar/correct/updated pack data

+ 3 - 1
src/binary.h

@@ -12,7 +12,9 @@ extern int checked_bin_buf;
 #  define GET_CONF              BIT4
 
 void check_sum(const char *, const char *, bool);
-void write_settings(const char *, int, bool);
+void write_settings(const char *, int, bool, int initialized = -1);
+bool check_bin_initialized(const char *fname);
+bool check_bin_compat(const char *fname);
 void conf_to_bin(conf_t *, bool, int);
 void reload_bin_data();
 #endif /* !_BINARY_H */

+ 10 - 1
src/misc.c

@@ -855,12 +855,21 @@ int updatebin(int idx, char *par, int secs)
     return 1;
   }
 
+  /* Check if the new binary is compatible */
+  int initialized = (int)check_bin_initialized(path);
+  if (!initialized && !check_bin_compat(path)) {
+    logidx(idx, STR("New binary must be initialized as pack structure has been changed in new version."));
+    free(path);
+    return 1;
+  }
+
+
   /* make a backup just in case. */
 
   simple_snprintf(buf, sizeof(buf), STR("%s/.bin.old"), conf.datadir);
   copyfile(binname, buf);
 
-  write_settings(path, -1, 0);	/* re-write the binary with our packdata */
+  write_settings(path, -1, 0, initialized);	/* re-write the binary with our packdata */
 
   Tempfile *conffile = new Tempfile("conf");
 

+ 2 - 1
src/settings.h

@@ -2,7 +2,8 @@
 #define _SETTINGS_H
 #define PREFIXLEN 16
 
-#define SETTINGS_VER 1
+/* !!! THIS MUST BE CHANGED WHEN CHANGING THE PACK STRUCT OR ALGORITHMS !!! */
+#define SETTINGS_VER 2
 
 typedef struct settings_struct {
   char prefix[PREFIXLEN];