Change check_mailbox to delegate to the child_ops->check_mailbox if
the compressed mailbox has changed.  This allows the mailbox to
properly recover if both the decompressed mailbox and compressed file
have changed.

Change sync_mailbox to call check_mailbox before attempting to sync.
This will prevent overwriting external changes to the compressed
mailbox.


# HG changeset patch
# User Kevin McCarthy <ke...@8t8.us>
# Date 1478734910 28800
#      Wed Nov 09 15:41:50 2016 -0800
# Node ID c24e9d27e0522d95a103ba5662562f714ea1379b
# Parent  6044c9d792c07d561a57fd501b6c8794f6b8c4b5
Compress: fix check_mailbox and sync_mailbox.

Change check_mailbox to delegate to the child_ops->check_mailbox if
the compressed mailbox has changed.  This allows the mailbox to
properly recover if both the decompressed mailbox and compressed file
have changed.

Change sync_mailbox to call check_mailbox before attempting to sync.
This will prevent overwriting external changes to the compressed
mailbox.

diff --git a/compress.c b/compress.c
--- a/compress.c
+++ b/compress.c
@@ -643,40 +643,37 @@
 {
   if (!ctx)
     return -1;
 
   COMPRESS_INFO *ci = ctx->compress_info;
   if (!ci)
     return -1;
 
+  struct mx_ops *ops = ci->child_ops;
+  if (!ops)
+    return -1;
+
   int size = get_size (ctx->realpath);
   if (size == ci->size)
     return 0;
 
-  /* TODO: this is a copout.  We should reopen the compressed mailbox
-   * and call mutt_reopen_mailbox. */
-  if (ctx->changed)
+  if (!lock_realpath (ctx, 0))
   {
-    mutt_free_compress_info (ctx);
-    mx_fastclose_mailbox (ctx);
-    mutt_error (_("Mailbox was corrupted!"));
+    mutt_error (_("Unable to lock mailbox!"));
     return -1;
   }
 
-  /* TODO: this block leaks memory.  this is doing it all wrong */
-  close_mailbox (ctx);
+  int rc = execute_command (ctx, ci->open, _("Decompressing %s"));
+  store_size (ctx);
+  unlock_realpath (ctx);
+  if (rc == 0)
+    return -1;
 
-  const char *path = ctx->path;
-  ctx->path = NULL;
-
-  mx_open_mailbox (path, 0, ctx);
-  FREE(&path);
-
-  return MUTT_REOPENED;
+  return ops->check (ctx, index_hint);
 }
 
 
 /**
  * open_message - Delegated to mbox handler
  */
 static int
 open_message (CONTEXT *ctx,  MESSAGE *msg, int msgno)
@@ -849,37 +846,37 @@
     return -1;
 
   if (!lock_realpath (ctx, 1))
   {
     mutt_error (_("Unable to lock mailbox!"));
     return -1;
   }
 
-  /* TODO: check if mailbox changed first! */
-
-  int rc = ops->sync (ctx, index_hint);
+  int rc = check_mailbox (ctx, index_hint);
   if (rc != 0)
-  {
-    unlock_realpath (ctx);
-    return rc;
-  }
+    goto sync_cleanup;
+
+  rc = ops->sync (ctx, index_hint);
+  if (rc != 0)
+    goto sync_cleanup;
 
   rc = execute_command (ctx, ci->close, _("Compressing %s"));
   if (rc == 0)
   {
-    unlock_realpath (ctx);
-    return -1;
+    rc = -1;
+    goto sync_cleanup;
   }
 
-  store_size (ctx);
+  rc = 0;
 
+sync_cleanup:
+  store_size (ctx);
   unlock_realpath (ctx);
-
-  return 0;
+  return rc;
 }
 
 /**
  * mutt_comp_valid_command - Is this command string allowed?
  * @cmd:  Command string
  *
  * A valid command string must have both "%f" (from file) and "%t" (to file).
  * We don't check if we can actually run the command.

Reply via email to