Jelajahi Sumber

Merge branch 'update-fix-uninitialized-problems'

* update-fix-uninitialized-problems:
  * Allow -3 to be ran before binary is initialized
  * Remove unused variable
  * Fix problem of upgrading with uninitialized binaries causing corruption
Bryan Drewery 17 tahun lalu
induk
melakukan
94a6b057e1
6 mengubah file dengan 50 tambahan dan 9 penghapusan
  1. 1 0
      doc/UPDATES
  2. 28 3
      src/binary.c
  3. 3 1
      src/binary.h
  4. 6 3
      src/main.c
  5. 10 1
      src/misc.c
  6. 2 1
      src/settings.h

+ 1 - 0
doc/UPDATES

@@ -32,6 +32,7 @@
 * Lower DNS lookup timeout from 40 seconds to 10 seconds
 * Use random query ids for DNS lookups
 * Fix problem of bots never reconnecting to hub after being up for long periods.
+* Fix problem of upgrading with uninitialized binaries causing corruption (will kick in on future upgrades)
 
 1.2.16 - http://wraith.botpack.net/milestone/1.2.16
 * Add 'set altchars' so that alternative characters used for nicks can be changed. (fixes #418)

+ 28 - 3
src/binary.c

@@ -565,7 +565,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;
@@ -581,12 +581,37 @@ 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)
+{
+  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 */

+ 6 - 3
src/main.c

@@ -344,9 +344,6 @@ static void dtx_arg(int& argc, char *argv[])
         exit(0);
       case '2':		/* used for testing new binary through update */
         exit(2);
-      case '3':		/* return the size of our settings struct */
-        printf("%d %zu\n", SETTINGS_VER, sizeof(settings_t));
-        exit(0);
       case '4':
         readconf(optarg, CONF_ENC);
         expand_tilde(&conf.binpath);
@@ -767,6 +764,12 @@ printf("out: %s\n", out);
     exit(5);				/* not initialized */
   }
 
+  /* return the size of our settings struct */
+  if (argc == 2 && !strcmp(argv[1], STR("-3"))) {
+    printf("%d %zu\n", SETTINGS_VER, sizeof(settings_t));
+    exit(0);
+  }
+
   {
     bool read_stdin = 0;
     if (argc == 2 && !strcmp(argv[1], STR("-Q")))

+ 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];