Commit d3705ea8 authored by Kevin J. McCarthy's avatar Kevin J. McCarthy

Create mx_ops.sync operation. Refactor compress to use the mx_ops.sync.

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.
parent f46e648f
......@@ -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,
......
......@@ -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;
......
......@@ -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 */
};
......@@ -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,
};
......@@ -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,
};
......@@ -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 *);
......
......@@ -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 */
......
......@@ -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 *);
......
......@@ -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,
};
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment