]> granicus.if.org Git - mutt/commitdiff
Create mx_ops.sync operation. Refactor compress to use the mx_ops.sync.
authorKevin McCarthy <kevin@8t8.us>
Mon, 14 Nov 2016 04:02:35 +0000 (20:02 -0800)
committerKevin McCarthy <kevin@8t8.us>
Mon, 14 Nov 2016 04:02:35 +0000 (20:02 -0800)
Change compress.sync_mailbox() to lock the compressed mailbox around
both the tempfile sync and compress operations.  This will prevent
changes made inbetween the two syncs from being overwritten.

Thanks to Damien Riegel for his original patch refactoring
mx_ops.sync, which this patch is partially based upon.

compress.c
compress.h
imap/imap.c
mbox.c
mh.c
mutt.h
mx.c
mx.h
pop.c
pop.h

index 681fffcf4823fcce2ba4713c6ab0e8f5707b4023..b7fb06eda86da6ca0b1a1578c2aaf4d19ee6e43f 100644 (file)
@@ -816,18 +816,18 @@ mutt_comp_can_read (const char *path)
 }
 
 /**
- * mutt_comp_sync - Save changes to the compressed mailbox file
+ * sync_mailbox - Save changes to the compressed mailbox file
  * @ctx: Mailbox to sync
  *
- * Changes in Mutt only affect the tmp file.  Calling mutt_comp_sync()
+ * Changes in Mutt only affect the tmp file.  Calling sync_mailbox()
  * will commit them to the compressed file.
  *
  * Returns:
  *       0: Success
  *      -1: Failure
  */
-int
-mutt_comp_sync (CONTEXT *ctx)
+static int
+sync_mailbox (CONTEXT *ctx, int *index_hint)
 {
   if (!ctx)
     return -1;
@@ -842,22 +842,36 @@ mutt_comp_sync (CONTEXT *ctx)
     return -1;
   }
 
-  /* TODO: need to refactor sync so we can lock around the
-   * path sync as well as the compress operation */
+  struct mx_ops *ops = ci->child_ops;
+  if (!ops)
+    return -1;
+
   if (!lock_realpath (ctx, 1))
   {
     mutt_error (_("Unable to lock mailbox!"));
     return -1;
   }
 
-  int rc = execute_command (ctx, ci->close, _("Compressing %s"));
+  /* TODO: check if mailbox changed first! */
+
+  int rc = ops->sync (ctx, index_hint);
+  if (rc != 0)
+  {
+    unlock_realpath (ctx);
+    return rc;
+  }
+
+  rc = execute_command (ctx, ci->close, _("Compressing %s"));
   if (rc == 0)
+  {
+    unlock_realpath (ctx);
     return -1;
-
-  unlock_realpath (ctx);
+  }
 
   store_size (ctx);
 
+  unlock_realpath (ctx);
+
   return 0;
 }
 
@@ -894,6 +908,7 @@ struct mx_ops mx_comp_ops =
   .open_append  = open_append_mailbox,
   .close        = close_mailbox,
   .check        = check_mailbox,
+  .sync         = sync_mailbox,
   .open_msg     = open_message,
   .close_msg    = close_message,
   .commit_msg   = commit_message,
index f525c70b3604cdab36518e528bbadcb10df282bf..0c545ee43cd1d88f3a5813f42163a2deef3429a9 100644 (file)
@@ -23,7 +23,6 @@ void mutt_free_compress_info (CONTEXT *ctx);
 
 int mutt_comp_can_append    (CONTEXT *ctx);
 int mutt_comp_can_read      (const char *path);
-int mutt_comp_sync          (CONTEXT *ctx);
 int mutt_comp_valid_command (const char *cmd);
 
 extern struct mx_ops mx_comp_ops;
index 729284dba83191562d68ff803ad0a90d75c0f501..89bbdb848a08dc91ef29a96240295dae47300ee8 100644 (file)
@@ -2188,4 +2188,5 @@ struct mx_ops mx_imap_ops = {
   .commit_msg = imap_commit_message,
   .open_new_msg = imap_open_new_message,
   .check = imap_check_mailbox_reopen,
+  .sync = NULL,      /* imap syncing is handled by imap_sync_mailbox */
 };
diff --git a/mbox.c b/mbox.c
index 13fc3d626df4e99d95999d78761b2b4b27cd3fda..37f426d8e55b7c36a5eae72624d24f10e6278e09 100644 (file)
--- a/mbox.c
+++ b/mbox.c
@@ -802,7 +802,7 @@ void mbox_reset_atime (CONTEXT *ctx, struct stat *st)
  *     0       success
  *     -1      failure
  */
-int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint)
+static int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint)
 {
   char tempfile[_POSIX_PATH_MAX];
   char buf[32];
@@ -817,6 +817,7 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint)
   FILE *fp = NULL;
   progress_t progress;
   char msgbuf[STRING];
+  BUFFY *tmp = NULL;
 
   /* sort message by their position in the mailbox on disk */
   if (Sort != SORT_ORDER)
@@ -1114,6 +1115,13 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint)
   unlink (tempfile); /* remove partial copy of the mailbox */
   mutt_unblock_signals ();
 
+  if (option(OPTCHECKMBOXSIZE))
+  {
+    tmp = mutt_find_mailbox (ctx->path);
+    if (tmp && tmp->new == 0)
+      mutt_update_mailbox (tmp);
+  }
+
   return (0); /* signal success */
 
 bail:  /* Come here in case of disaster */
@@ -1354,6 +1362,7 @@ struct mx_ops mx_mbox_ops = {
   .commit_msg = mbox_commit_message,
   .open_new_msg = mbox_open_new_message,
   .check = mbox_check_mailbox,
+  .sync = mbox_sync_mailbox,
 };
 
 struct mx_ops mx_mmdf_ops = {
@@ -1365,4 +1374,5 @@ struct mx_ops mx_mmdf_ops = {
   .commit_msg = mmdf_commit_message,
   .open_new_msg = mbox_open_new_message,
   .check = mbox_check_mailbox,
+  .sync = mbox_sync_mailbox,
 };
diff --git a/mh.c b/mh.c
index 371656af4c6b1502b433d2ff1a1e88aa8108c726..41493f91a1a446b61dcad7b4102d63c1bc82abad 100644 (file)
--- a/mh.c
+++ b/mh.c
@@ -2536,6 +2536,7 @@ struct mx_ops mx_maildir_ops = {
   .commit_msg = maildir_commit_message,
   .open_new_msg = maildir_open_new_message,
   .check = maildir_check_mailbox,
+  .sync = mh_sync_mailbox,
 };
 
 struct mx_ops mx_mh_ops = {
@@ -2547,4 +2548,5 @@ struct mx_ops mx_mh_ops = {
   .commit_msg = mh_commit_message,
   .open_new_msg = mh_open_new_message,
   .check = mh_check_mailbox,
+  .sync = mh_sync_mailbox,
 };
diff --git a/mutt.h b/mutt.h
index c63a1eeb13f7ab79c750150cce4d3ea54df0f3c0..98b77ffac834483e0da36eb43039ede79c269b89 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -908,6 +908,7 @@ struct mx_ops
   int (*open_append) (struct _context *, int flags);
   int (*close) (struct _context *);
   int (*check) (struct _context *ctx, int *index_hint);
+  int (*sync) (struct _context *ctx, int *index_hint);
   int (*open_msg) (struct _context *, struct _message *, int msgno);
   int (*close_msg) (struct _context *, struct _message *);
   int (*commit_msg) (struct _context *, struct _message *);
diff --git a/mx.c b/mx.c
index 033ee181baf2cd7776beb2dfd28aa11ea3b36f5a..a961937754711db45d362a0ab604b2423c68e315 100644 (file)
--- a/mx.c
+++ b/mx.c
@@ -682,56 +682,13 @@ void mx_fastclose_mailbox (CONTEXT *ctx)
 /* save changes to disk */
 static int sync_mailbox (CONTEXT *ctx, int *index_hint)
 {
-  BUFFY *tmp = NULL;
-  int rc = -1;
+  if (!ctx->mx_ops || !ctx->mx_ops->sync)
+    return -1;
 
   if (!ctx->quiet)
     mutt_message (_("Writing %s..."), ctx->path);
 
-  switch (ctx->magic)
-  {
-    case MUTT_MBOX:
-    case MUTT_MMDF:
-      rc = mbox_sync_mailbox (ctx, index_hint);
-      if (option(OPTCHECKMBOXSIZE))
-       tmp = mutt_find_mailbox (ctx->path);
-      break;
-      
-    case MUTT_MH:
-    case MUTT_MAILDIR:
-      rc = mh_sync_mailbox (ctx, index_hint);
-      break;
-      
-#ifdef USE_IMAP
-    case MUTT_IMAP:
-      /* extra argument means EXPUNGE */
-      rc = imap_sync_mailbox (ctx, 1, index_hint);
-      break;
-#endif /* USE_IMAP */
-
-#ifdef USE_POP
-    case MUTT_POP:
-      rc = pop_sync_mailbox (ctx, index_hint);
-      break;
-#endif /* USE_POP */
-  }
-
-#if 0
-  if (!ctx->quiet && !ctx->shutup && rc == -1)
-    mutt_error ( _("Could not synchronize mailbox %s!"), ctx->path);
-#endif
-  
-  if (tmp && tmp->new == 0)
-    mutt_update_mailbox (tmp);
-
-#ifdef USE_COMPRESSED
-  /* If everything went well, the mbox handler saved the changes to our
-   * temporary file.  Next, mutt_comp_sync() will compress the temporary file. */
-  if ((rc == 0) && ctx->compress_info)
-    return mutt_comp_sync (ctx);
-#endif
-
-  return rc;
+  return ctx->mx_ops->sync (ctx, index_hint);
 }
 
 /* move deleted mails to the trash folder */
diff --git a/mx.h b/mx.h
index 6b3c535ea186e26bd02df2e7303c95669397a708..f5563d82a276ef6ee4c4812e2cf1d19d317f6e00 100644 (file)
--- a/mx.h
+++ b/mx.h
@@ -47,7 +47,6 @@ WHERE short DefaultMagic INITVAL (MUTT_MBOX);
 #define MMDF_SEP "\001\001\001\001\n"
 #define MAXLOCKATTEMPT 5
 
-int mbox_sync_mailbox (CONTEXT *, int *);
 int mbox_lock_mailbox (CONTEXT *, int, int);
 int mbox_parse_mailbox (CONTEXT *);
 int mmdf_parse_mailbox (CONTEXT *);
@@ -55,7 +54,6 @@ void mbox_unlock_mailbox (CONTEXT *);
 int mbox_check_empty (const char *);
 void mbox_reset_atime (CONTEXT *, struct stat *);
 
-int mh_sync_mailbox (CONTEXT *, int *);
 int mh_check_empty (const char *);
 
 int maildir_check_empty (const char *);
diff --git a/pop.c b/pop.c
index 294d71d8d5f1c3d6ee0fecc2f4277d457ec16bea..81f739af913529eaf89c56a457192637ffed174b 100644 (file)
--- a/pop.c
+++ b/pop.c
@@ -664,7 +664,7 @@ static int pop_close_message (CONTEXT *ctx, MESSAGE *msg)
 }
 
 /* update POP mailbox - delete messages from server */
-int pop_sync_mailbox (CONTEXT *ctx, int *index_hint)
+static int pop_sync_mailbox (CONTEXT *ctx, int *index_hint)
 {
   int i, j, ret = 0;
   char buf[LONG_STRING];
@@ -944,4 +944,5 @@ struct mx_ops mx_pop_ops = {
   .check = pop_check_mailbox,
   .commit_msg = NULL,
   .open_new_msg = NULL,
+  .sync = pop_sync_mailbox,
 };
diff --git a/pop.h b/pop.h
index 53454c67861048fdaf92b98ffd17d35f6c68c857..55e99eecce36e25a6755b524f877412bf72e95d1 100644 (file)
--- a/pop.h
+++ b/pop.h
@@ -105,7 +105,6 @@ void pop_logout (CONTEXT *);
 void pop_error (POP_DATA *, char *);
 
 /* pop.c */
-int pop_sync_mailbox (CONTEXT *, int *);
 int pop_close_mailbox (CONTEXT *);
 void pop_fetch_mail (void);