diff --git a/lib/mu-msg.c b/lib/mu-msg.c index c9359035..44e99fa1 100644 --- a/lib/mu-msg.c +++ b/lib/mu-msg.c @@ -902,3 +902,19 @@ mu_msg_move_to_maildir (MuMsg *self, const char *maildir, return self->_file ? TRUE : FALSE; } + + +/* + * Rename a message-file, keeping the same flags. This is useful for tricking + * some 3rd party progs such as mbsync + */ +gboolean +mu_msg_tickle (MuMsg *self, GError **err) +{ + g_return_val_if_fail (self, FALSE); + + return mu_msg_move_to_maildir (self, + mu_msg_get_maildir (self), + mu_msg_get_flags (self), + FALSE, TRUE, err); +} diff --git a/lib/mu-msg.h b/lib/mu-msg.h index 150d466f..0358cff8 100644 --- a/lib/mu-msg.h +++ b/lib/mu-msg.h @@ -476,6 +476,23 @@ gboolean mu_msg_move_to_maildir (MuMsg *msg, const char *maildir, GError **err); +/** + * Tickle a message -- ie., rxename a message while maintaining the maildir and + * flags. This can be useful when dealing with third-party tools such as mbsync + * that depend on changed filenames. + * + * @param msg a message with an existing file system path in an actual + * maildir + * @param err (may be NULL) may contain error information; note if the + * function return FALSE, err is not set for all error condition + * (ie. not for parameter error + * + * @return TRUE if it worked, FALSE otherwise + */ +gboolean mu_msg_tickle (MuMsg *msg, GError **err); + + + enum _MuMsgContactType { /* Reply-To:? */ MU_MSG_CONTACT_TYPE_TO = 0, MU_MSG_CONTACT_TYPE_FROM, diff --git a/mu/mu-cmd.c b/mu/mu-cmd.c index 4c2ee909..d887f32f 100644 --- a/mu/mu-cmd.c +++ b/mu/mu-cmd.c @@ -412,6 +412,33 @@ mu_cmd_remove (MuStore *store, MuConfig *opts, GError **err) return foreach_msg_file (store, opts, remove_path_func, err); } +static gboolean +tickle_func (MuStore *store, const char *path, GError **err) +{ + MuMsg *msg; + gboolean rv; + + msg = mu_msg_new_from_file (path, NULL, err); + if (!msg) + return FALSE; + + rv = mu_msg_tickle (msg, err); + mu_msg_unref (msg); + + return rv; +} + + +MuError +mu_cmd_tickle (MuStore *store, MuConfig *opts, GError **err) +{ + g_return_val_if_fail (opts, MU_ERROR_INTERNAL); + g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_TICKLE, + MU_ERROR_INTERNAL); + + return foreach_msg_file (store, opts, tickle_func, err); +} + struct _VData { MuMsgPartSigStatus combined_status; char *report; @@ -632,6 +659,8 @@ mu_cmd_execute (MuConfig *opts, GError **err) merr = with_store (mu_cmd_add, opts, FALSE, err); break; case MU_CONFIG_CMD_REMOVE: merr = with_store (mu_cmd_remove, opts, FALSE, err); break; + case MU_CONFIG_CMD_TICKLE: + merr = with_store (mu_cmd_tickle, opts, FALSE, err); break; case MU_CONFIG_CMD_SERVER: merr = with_store (mu_cmd_server, opts, FALSE, err); break; default: diff --git a/mu/mu-cmd.h b/mu/mu-cmd.h index 0ec483ca..b8693ec0 100644 --- a/mu/mu-cmd.h +++ b/mu/mu-cmd.h @@ -151,6 +151,18 @@ MuError mu_cmd_add (MuStore *store, MuConfig *opts, GError **err); */ MuError mu_cmd_remove (MuStore *store, MuConfig *opts, GError **err); +/** + * execute the tickle command + * + * @param store store object to use + * @param opts configuration options + * @param err receives error information, or NULL + * + * @return MU_OK (0) if the command succeeds, + * some error code otherwise + */ +MuError mu_cmd_tickle (MuStore *store, MuConfig *opts, GError **err); + /** * execute the server command diff --git a/mu/mu-config.c b/mu/mu-config.c index bd744f86..8e3c3532 100644 --- a/mu/mu-config.c +++ b/mu/mu-config.c @@ -471,6 +471,7 @@ cmd_from_string (const char *str) { "remove", MU_CONFIG_CMD_REMOVE }, { "script", MU_CONFIG_CMD_SCRIPT }, { "server", MU_CONFIG_CMD_SERVER }, + { "tickle", MU_CONFIG_CMD_TICKLE }, { "verify", MU_CONFIG_CMD_VERIFY }, { "view", MU_CONFIG_CMD_VIEW } }; diff --git a/mu/mu-config.h b/mu/mu-config.h index d4574168..e192d5cc 100644 --- a/mu/mu-config.h +++ b/mu/mu-config.h @@ -74,6 +74,7 @@ enum _MuConfigCmd { MU_CONFIG_CMD_REMOVE, MU_CONFIG_CMD_SCRIPT, MU_CONFIG_CMD_SERVER, + MU_CONFIG_CMD_TICKLE, MU_CONFIG_CMD_VERIFY, MU_CONFIG_CMD_VIEW,