]> granicus.if.org Git - neomutt/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)
committerRichard Russon <rich@flatcap.org>
Fri, 18 Nov 2016 21:42:20 +0000 (21:42 +0000)
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.

13 files changed:
compress.c
compress.h
imap/imap.c
mbox.c
mh.c
mutt.h
mutt_notmuch.c
mx.c
mx.h
nntp.c
nntp.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 7e1c21694c5329ebf647d0699eff97662d9f566a..fb6689809be68e495ab477b708375b1649a18761 100644 (file)
@@ -2189,4 +2189,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 45af0b33ced71200f03985ff1893ca64540bcb78..fae0cfbb25683c8a754c4141bb9f753d13e176aa 100644 (file)
--- a/mh.c
+++ b/mh.c
@@ -2627,6 +2627,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 = {
@@ -2638,4 +2639,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 b440a6bccb224c9df564bbdced99110482a81d52..0fe027f2bbdcf4e1e2abff9803f5f5a3dc62b61e 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -992,6 +992,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 *);
index 097ec0205f259980eaf86b2e3d7c1ded0b4494d6..28d2889c1e4fd9c2edad3c80d35f3f37f66171a9 100644 (file)
@@ -1030,7 +1030,7 @@ static void append_message(CONTEXT *ctx,
        ctx->msgcount++;
 
        if (newpath) {
-               /* remember that file has been moved -- nm_sync() will update the DB */
+               /* remember that file has been moved -- nm_sync_mailbox() will update the DB */
                struct nm_hdrdata *hd = (struct nm_hdrdata *) h->data;
 
                if (hd) {
@@ -1604,7 +1604,7 @@ int nm_update_filename(CONTEXT *ctx, const char *old, const char *new, HEADER *h
        return rc;
 }
 
-int nm_sync(CONTEXT *ctx, int *index_hint)
+int nm_sync_mailbox(CONTEXT *ctx, int *index_hint)
 {
        struct nm_ctxdata *data = get_ctxdata(ctx);
        int i, rc = 0;
@@ -2072,6 +2072,7 @@ struct mx_ops mx_notmuch_ops = {
         .open_append  = NULL,
        .close        = deinit_context,
        .check        = nm_check_database,
+       .sync         = nm_sync_mailbox,
        .open_msg     = nm_open_message,
        .close_msg    = nm_close_message,
        .commit_msg   = nm_commit_message,
diff --git a/mx.c b/mx.c
index eb7bcd86d5528ae901935445ffa1dac14a7976ef..3173e860ab071d812495823a586d2e54f02e022b 100644 (file)
--- a/mx.c
+++ b/mx.c
@@ -745,69 +745,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 */
-
-#ifdef USE_NNTP
-    case MUTT_NNTP:
-      rc = nntp_sync_mailbox (ctx);
-      break;
-#endif /* USE_NNTP */
-
-#ifdef USE_NOTMUCH
-    case MUTT_NOTMUCH:
-      rc = nm_sync (ctx, index_hint);
-      break;
-#endif /* USE_NOTMUCH */
-
-  }
-
-#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 2f62abfdaf220bd140e166c2b7d2e8694070a64d..f084bc301132a528243baa2b150e68b39da907b3 100644 (file)
--- a/mx.h
+++ b/mx.h
@@ -51,7 +51,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 *);
@@ -59,7 +58,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/nntp.c b/nntp.c
index 494149ec4ee985e650d29ec0e4da8093bed68a74..d5d41170a62d1a813d1ebec687b500267bb66558 100644 (file)
--- a/nntp.c
+++ b/nntp.c
@@ -1760,7 +1760,7 @@ int nntp_post (const char *msg) {
 }
 
 /* Save changes to .newsrc and cache */
-int nntp_sync_mailbox (CONTEXT *ctx)
+int nntp_sync_mailbox (CONTEXT *ctx, int *index_hint)
 {
   NNTP_DATA *nntp_data = ctx->data;
   int rc, i;
@@ -1770,7 +1770,7 @@ int nntp_sync_mailbox (CONTEXT *ctx)
 
   /* check for new articles */
   nntp_data->nserv->check_time = 0;
-  rc = nntp_check_mailbox (ctx, NULL);
+  rc = nntp_check_mailbox (ctx, index_hint);
   if (rc)
     return rc;
 
@@ -2447,6 +2447,7 @@ struct mx_ops mx_nntp_ops = {
   .open_append  = NULL,
   .close        = nntp_fastclose_mailbox,
   .check        = nntp_check_mailbox,
+  .sync         = nntp_sync_mailbox,
   .open_msg     = nntp_fetch_message,
   .close_msg    = nntp_close_message,
   .commit_msg   = NULL,
diff --git a/nntp.h b/nntp.h
index 9db9ef59299028f854a9df3e24e9e3a32bf63b0b..2c1f4347a2854d33bf570323fcc1458cde22e1bd 100644 (file)
--- a/nntp.h
+++ b/nntp.h
@@ -143,7 +143,7 @@ NNTP_DATA *mutt_newsgroup_uncatchup (NNTP_SERVER *, char *);
 int nntp_active_fetch (NNTP_SERVER *);
 int nntp_newsrc_update (NNTP_SERVER *);
 int nntp_open_mailbox (CONTEXT *);
-int nntp_sync_mailbox (CONTEXT *);
+int nntp_sync_mailbox (CONTEXT *ctx, int *index_hint);
 int nntp_check_mailbox (CONTEXT *, int*);
 int nntp_fetch_message (CONTEXT *, MESSAGE *, int);
 int nntp_post (const char *);
diff --git a/pop.c b/pop.c
index f8d4d79a22fb571b6b0878b2e0bea53bb1daa70e..2a708d0ff54031406928767a5f141111152f2ed6 100644 (file)
--- a/pop.c
+++ b/pop.c
@@ -665,7 +665,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];
@@ -946,4 +946,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);