diff --git a/src/lib-sieve/edit-mail.c b/src/lib-sieve/edit-mail.c index 9a6b751f683aa2a8efa0df0d727b76175fee7772..ed6f31dcef6250c5a5a199945d1fab64d68acfcb 100644 --- a/src/lib-sieve/edit-mail.c +++ b/src/lib-sieve/edit-mail.c @@ -405,6 +405,10 @@ void edit_mail_unwrap(struct edit_mail **edmail) struct mail *edit_mail_get_mail(struct edit_mail *edmail) { + /* Return wrapped mail when nothing is modified yet */ + if ( !edmail->modified ) + return &edmail->wrapped->mail; + return &edmail->mail.mail; } @@ -1337,17 +1341,21 @@ static int edit_mail_get_special { struct edit_mail *edmail = (struct edit_mail *)mail; - switch (field) { - case MAIL_FETCH_GUID: - /* This is in essence a new message */ - *value_r = ""; - return 0; - case MAIL_FETCH_UIDL_FILE_NAME: - /* Prevent hardlink copying */ - *value_r = ""; - return 0; - default: - break; + if ( edmail->modified ) { + /* Block certain fields when modified */ + + switch (field) { + case MAIL_FETCH_GUID: + /* This is in essence a new message */ + *value_r = ""; + return 0; + case MAIL_FETCH_UIDL_FILE_NAME: + /* Prevent hardlink copying */ + *value_r = ""; + return 0; + default: + break; + } } return edmail->wrapped->v.get_special(&edmail->wrapped->mail, field, value_r); @@ -1357,7 +1365,7 @@ static struct mail *edit_mail_get_real_mail(struct mail *mail) { struct edit_mail *edmail = (struct edit_mail *)mail; - return edmail->wrapped->v.get_real_mail(&edmail->wrapped->mail); + return edit_mail_get_mail(edmail); } static void edit_mail_update_flags diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index 1001c12f2f1bd4caf28081c8c08e979bd4bc40e1..bb610a4e1636f9afab34467e46519bcecdac1af0 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -467,7 +467,8 @@ static bool act_store_execute struct act_store_transaction *trans = (struct act_store_transaction *) tr_context; struct mail *mail = ( action->mail != NULL ? - action->mail : aenv->msgdata->mail ); + action->mail : aenv->msgdata->mail ); + struct mail *real_mail = mail_get_real_mail(mail); struct mail_save_context *save_ctx; struct mail_keywords *keywords = NULL; bool result = TRUE; @@ -483,12 +484,14 @@ static bool act_store_execute return FALSE; /* If the message originates from the target mailbox, only update the flags - * and keywords + * and keywords (if not read-only) */ - if ( mailbox_backends_equal(trans->box, mail->box) ) { + if ( mailbox_backends_equal(trans->box, mail->box) || + (real_mail != mail && mailbox_backends_equal(trans->box, real_mail->box)) ) + { trans->redundant = TRUE; - if ( trans->flags_altered ) { + if ( trans->flags_altered && !mailbox_is_readonly(mail->box) ) { keywords = act_store_keywords_create (aenv, &trans->keywords, mail->box); @@ -501,6 +504,18 @@ static bool act_store_execute } return TRUE; + + /* If the message is modified, only store it in the source mailbox when it is + * not opened read-only. Mail structs of modified messages have their own + * mailbox, unrelated to the orignal mail, so this case needs to be handled + * separately. + */ + } else if ( mail != aenv->msgdata->mail + && mailbox_is_readonly(aenv->msgdata->mail->box) + && ( mailbox_backends_equal(trans->box, aenv->msgdata->mail->box) ) ) { + + trans->redundant = TRUE; + return TRUE; } /* Mark attempt to store in default mailbox */