From 14e91a15ae136681f48284b70e0f16d47711bcff Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sat, 19 Jun 2010 13:07:10 +0200 Subject: [PATCH] Cleaned up mail storage-related code (modified patch by Timo Sirainen). --- .../plugins/mailbox/tag-mailbox-create.c | 60 ++++----- .../plugins/mailbox/tst-mailboxexists.c | 4 +- src/lib-sieve/sieve-actions.c | 115 ++++++++---------- src/lib-sieve/sieve-actions.h | 8 +- src/lib-sieve/sieve-types.h | 2 +- src/plugins/lda-sieve/lda-sieve-plugin.c | 2 +- src/sieve-tools/sieve-filter.c | 2 +- src/sieve-tools/sieve-test.c | 2 +- src/testsuite/testsuite-mailstore.c | 6 +- src/testsuite/testsuite-mailstore.h | 4 +- src/testsuite/testsuite-script.c | 5 +- src/testsuite/testsuite.c | 2 +- 12 files changed, 89 insertions(+), 123 deletions(-) diff --git a/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c b/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c index f78142f4f..a1e91d180 100644 --- a/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c +++ b/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c @@ -122,54 +122,42 @@ static bool seff_mailbox_create_pre_execute struct act_store_transaction *trans = (struct act_store_transaction *) tr_context; struct mail_storage **storage = &(aenv->exec_status->last_storage); - enum mailbox_flags flags = - MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_SAVEONLY | - MAILBOX_FLAG_POST_SESSION; - struct mailbox *box = NULL; + enum mail_error error; /* Check whether creation is necessary */ - if ( trans->box != NULL || trans->redundant || trans->disabled ) + if ( trans->box == NULL || trans->redundant || trans->disabled ) return TRUE; - /* Check availability of namespace and folder name */ - if ( trans->namespace == NULL || trans->folder == NULL ) - return FALSE; - /* Check whether creation has a chance of working */ - if ( trans->error_code != MAIL_ERROR_NONE - && trans->error_code != MAIL_ERROR_NOTFOUND ) + if ( trans->error_code != MAIL_ERROR_NONE && + trans->error_code != MAIL_ERROR_NOTFOUND ) return FALSE; - *storage = trans->namespace->storage; + *storage = mailbox_get_storage(trans->box); - box = mailbox_alloc(trans->namespace->list, trans->folder, flags); /* Create mailbox */ - if ( mailbox_create(box, NULL, FALSE) < 0 ) { - mailbox_free(&box); - box = NULL; - - } else { - /* Subscribe to it if necessary */ - if ( aenv->scriptenv->mailbox_autosubscribe ) { - (void)mailbox_list_set_subscribed - (trans->namespace->list, trans->folder, TRUE); + if ( mailbox_create(trans->box, NULL, FALSE) < 0 ) { + (void)mail_storage_get_last_error(*storage, &error); + if ( error != MAIL_ERROR_EXISTS ) { + sieve_act_store_get_storage_error(aenv, trans); + return FALSE; } + } + /* Subscribe to it if necessary */ + if ( aenv->scriptenv->mailbox_autosubscribe ) { + (void)mailbox_list_set_subscribed + (mailbox_get_namespace(trans->box)->list, + mailbox_get_name(trans->box), TRUE); + } - /* Try opening again */ - if ( mailbox_sync(box, 0) < 0 ) { - /* Failed definitively */ - mailbox_free(&box); - box = NULL; - } - } - - /* Fetch error */ - if ( box == NULL ) - sieve_act_store_get_storage_error(aenv, trans); + /* Try opening again */ + if ( mailbox_sync(trans->box, 0) < 0 ) { + /* Failed definitively */ + sieve_act_store_get_storage_error(aenv, trans); + return FALSE; + } - trans->box = box; - - return ( box != NULL ); + return TRUE; } diff --git a/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c b/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c index 208f806ee..9c57204c1 100644 --- a/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c +++ b/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c @@ -124,7 +124,7 @@ static int tst_mailboxexists_operation_execute sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "mailboxexists test"); - if ( renv->scriptenv->namespaces != NULL ) { + if ( renv->scriptenv->user != NULL ) { mailbox_item = NULL; while ( (result=sieve_coded_stringlist_next_item (mailbox_names, &mailbox_item)) @@ -134,7 +134,7 @@ static int tst_mailboxexists_operation_execute struct mailbox *box; /* Find the namespace */ - ns = mail_namespace_find(renv->scriptenv->namespaces, &mailbox); + ns = mail_namespace_find(renv->scriptenv->user->namespaces, &mailbox); if ( ns == NULL) { all_exist = FALSE; break; diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index dee8cbfe6..ffadf2752 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -265,11 +265,11 @@ void sieve_act_store_get_storage_error { pool_t pool = sieve_result_pool(aenv->result); - trans->error = p_strdup(pool, - mail_storage_get_last_error(trans->namespace->storage, &trans->error_code)); + trans->error = p_strdup(pool, + mail_storage_get_last_error(mailbox_get_storage(trans->box), + &trans->error_code)); } - /* Equality */ static bool act_store_equals @@ -330,18 +330,22 @@ static void act_store_print /* Action implementation */ -static struct mailbox *act_store_mailbox_open +static bool act_store_mailbox_open (const struct sieve_action_exec_env *aenv, const char **mailbox, - struct mail_namespace **ns_r, const char **folder_r) + struct mailbox **box_r) { struct mail_storage **storage = &(aenv->exec_status->last_storage); enum mailbox_flags flags = MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_SAVEONLY | MAILBOX_FLAG_POST_SESSION; string_t *mailbox_mutf7; + struct mail_namespace *ns; struct mailbox *box; + const char *folder; enum mail_error error; + *box_r = NULL; + /* Deliveries to INBOX must always succeed, regardless of ACLs */ if (strcasecmp(*mailbox, "INBOX") == 0) { flags |= MAILBOX_FLAG_IGNORE_ACLS; @@ -353,37 +357,32 @@ static struct mailbox *act_store_mailbox_open if ( imap_utf8_to_utf7(*mailbox, mailbox_mutf7) < 0 ) { /* FIXME: check utf-8 validity at compiletime/runtime */ sieve_result_error(aenv, "mailbox name not utf-8: %s", *mailbox); - return NULL; + return FALSE; } - *folder_r = str_c(mailbox_mutf7); - *ns_r = mail_namespace_find(aenv->scriptenv->namespaces, folder_r); - if ( *ns_r == NULL) { - *storage = NULL; - return NULL; + folder = str_c(mailbox_mutf7); + ns = mail_namespace_find(aenv->scriptenv->user->namespaces, &folder); + if ( ns == NULL) { + sieve_result_error + (aenv, "failed to find namespace for mailbox '%s'", *mailbox); + return FALSE; } - if ( **folder_r == '\0' ) { + if ( *folder == '\0' ) { /* delivering to a namespace prefix means we actually want to * deliver to the INBOX instead */ - *folder_r = *mailbox = "INBOX"; + folder = *mailbox = "INBOX"; flags |= MAILBOX_FLAG_IGNORE_ACLS; - *ns_r = mail_namespace_find(aenv->scriptenv->namespaces, folder_r); - if ( *ns_r == NULL) { - *storage = NULL; - return NULL; - } - - *storage = (*ns_r)->storage; + ns = mail_namespace_find_inbox(aenv->scriptenv->user->namespaces); } /* First attempt at opening the box */ - box = mailbox_alloc((*ns_r)->list, *folder_r, flags); + *box_r = box = mailbox_alloc(ns->list, folder, flags); if ( mailbox_open(box) == 0 ) { /* Success */ - return box; + return TRUE; } /* Failed */ @@ -394,33 +393,28 @@ static struct mailbox *act_store_mailbox_open /* Only continue when the mailbox is missing and when we are allowed to * create it. */ - if ( !aenv->scriptenv->mailbox_autocreate || error != MAIL_ERROR_NOTFOUND ) { - mailbox_free(&box); - return NULL; - } + if ( error != MAIL_ERROR_NOTFOUND || !aenv->scriptenv->mailbox_autocreate ) + return FALSE; /* Try creating it. */ if ( mailbox_create(box, NULL, FALSE) < 0 ) { (void)mail_storage_get_last_error(*storage, &error); - if (error != MAIL_ERROR_EXISTS) { - mailbox_free(&box); - return NULL; - } + if (error != MAIL_ERROR_EXISTS) + return FALSE; } /* Subscribe to it if required */ if ( aenv->scriptenv->mailbox_autosubscribe ) { - (void)mailbox_list_set_subscribed((*ns_r)->list, *folder_r, TRUE); + (void)mailbox_list_set_subscribed(ns->list, folder, TRUE); } /* Try opening again */ if ( mailbox_sync(box, 0) < 0 ) { /* Failed definitively */ - mailbox_free(&box); - return NULL; + return FALSE; } - return box; + return TRUE; } static bool act_store_start @@ -431,11 +425,9 @@ static bool act_store_start const struct sieve_script_env *senv = aenv->scriptenv; const struct sieve_message_data *msgdata = aenv->msgdata; struct act_store_transaction *trans; - struct mail_namespace *ns = NULL; struct mailbox *box = NULL; - const char *folder; pool_t pool = sieve_result_pool(aenv->result); - bool disabled = FALSE, redundant = FALSE; + bool disabled = FALSE, redundant = FALSE, open_failed = FALSE; /* If context is NULL, the store action is the result of (implicit) keep */ if ( ctx == NULL ) { @@ -445,19 +437,19 @@ static bool act_store_start /* Open the requested mailbox */ - /* NOTE: The caller of the sieve library is allowed to leave namespaces set + /* NOTE: The caller of the sieve library is allowed to leave user set * to NULL. This implementation will then skip actually storing the message. */ - if ( senv->namespaces != NULL ) { - box = act_store_mailbox_open(aenv, &ctx->mailbox, &ns, &folder); + if ( senv->user != NULL ) { + if ( !act_store_mailbox_open(aenv, &ctx->mailbox, &box) ) { + open_failed = TRUE; /* Check whether we are trying to store the message in the folder it * originates from. In that case we skip actually storing it. */ - if ( box != NULL && mailbox_backends_equal(box, msgdata->mail->box) ) { + } else if ( mailbox_backends_equal(box, msgdata->mail->box) ) { mailbox_free(&box); box = NULL; - ns = NULL; redundant = TRUE; } } else { @@ -468,22 +460,19 @@ static bool act_store_start trans = p_new(pool, struct act_store_transaction, 1); trans->context = ctx; - trans->namespace = ns; - trans->folder = folder; trans->box = box; trans->flags = 0; trans->disabled = disabled; trans->redundant = redundant; + trans->error_code = MAIL_ERROR_NONE; - if ( ns != NULL && box == NULL ) + if ( open_failed ) sieve_act_store_get_storage_error(aenv, trans); - + *tr_context = (void *)trans; - return ( (box != NULL) - || (trans->error_code == MAIL_ERROR_NOTFOUND) - || disabled || redundant ); + return TRUE; } static struct mail_keywords *act_store_keywords_create @@ -545,10 +534,8 @@ static bool act_store_execute return TRUE; } - /* Exit early if namespace or mailbox are not available */ - if ( trans->namespace == NULL ) - return FALSE; - else if ( trans->box == NULL ) + /* Exit early if mailbox is not available */ + if ( trans->box == NULL ) return FALSE; /* Mark attempt to store in default mailbox */ @@ -582,7 +569,7 @@ static bool act_store_execute if ( mailbox_copy(&save_ctx, aenv->msgdata->mail) < 0 ) { sieve_act_store_get_storage_error(aenv, trans); result = FALSE; - } + } /* Deallocate keywords */ if ( keywords != NULL ) { @@ -608,11 +595,6 @@ static void act_store_log_status } else if ( trans->redundant ) { sieve_result_log(aenv, "left message in mailbox '%s'", mailbox_name); - /* Namespace not set? */ - } else if ( trans->namespace == NULL ) { - sieve_result_error - (aenv, "failed to find namespace for mailbox '%s'", mailbox_name); - /* Store failed? */ } else if ( !status ) { const char *errstr; @@ -621,7 +603,8 @@ static void act_store_log_status if ( trans->error != NULL ) errstr = trans->error; else - errstr = mail_storage_get_last_error(trans->namespace->storage, &error); + errstr = mail_storage_get_last_error + (mailbox_get_storage(trans->box), &error); sieve_result_error(aenv, "failed to store into mailbox '%s': %s", mailbox_name, errstr); @@ -652,24 +635,22 @@ static bool act_store_commit if ( trans->disabled ) { act_store_log_status(trans, aenv, FALSE, status); *keep = FALSE; + if ( trans->box != NULL ) + mailbox_free(&trans->box); return TRUE; } else if ( trans->redundant ) { act_store_log_status(trans, aenv, FALSE, status); aenv->exec_status->keep_original = TRUE; aenv->exec_status->message_saved = TRUE; + if ( trans->box != NULL ) + mailbox_free(&trans->box); return TRUE; } - /* Exit early if namespace is not available */ - if ( trans->namespace == NULL ) - return FALSE; - else if ( trans->box == NULL ) - return FALSE; - /* Mark attempt to use storage. Can only get here when all previous actions * succeeded. */ - aenv->exec_status->last_storage = trans->namespace->storage; + aenv->exec_status->last_storage = mailbox_get_storage(trans->box); /* Free mail object for stored message */ if ( trans->dest_mail != NULL ) diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index f84a7aaae..c858580e6 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -214,17 +214,13 @@ struct act_store_context { struct act_store_transaction { struct act_store_context *context; - struct mail_namespace *namespace; struct mailbox *box; struct mailbox_transaction_context *mail_trans; struct mail *dest_mail; - - const char *folder; - const char *folder_mutf7; - + const char *error; enum mail_error error_code; - + enum mail_flags flags; ARRAY_TYPE(const_string) keywords; diff --git a/src/lib-sieve/sieve-types.h b/src/lib-sieve/sieve-types.h index 5dc3de9c5..1d026c879 100644 --- a/src/lib-sieve/sieve-types.h +++ b/src/lib-sieve/sieve-types.h @@ -72,7 +72,7 @@ struct sieve_script_env { const char *action_log_format; /* Mail-related */ - struct mail_namespace *namespaces; + struct mail_user *user; const char *default_mailbox; bool mailbox_autocreate; bool mailbox_autosubscribe; diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c index 35b3497fb..35774e77f 100644 --- a/src/plugins/lda-sieve/lda-sieve-plugin.c +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c @@ -596,7 +596,7 @@ static int lda_sieve_run scriptenv.default_mailbox = mdctx->dest_mailbox_name; scriptenv.mailbox_autocreate = mdctx->set->lda_mailbox_autocreate; scriptenv.mailbox_autosubscribe = mdctx->set->lda_mailbox_autosubscribe; - scriptenv.namespaces = mdctx->dest_user->namespaces; + scriptenv.user = mdctx->dest_user; scriptenv.username = mdctx->dest_user->username; scriptenv.hostname = mdctx->set->hostname; scriptenv.postmaster_address = mdctx->set->postmaster_address; diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c index e0e79e900..868f2adc6 100644 --- a/src/sieve-tools/sieve-filter.c +++ b/src/sieve-tools/sieve-filter.c @@ -413,7 +413,7 @@ int main(int argc, char **argv) memset(&scriptenv, 0, sizeof(scriptenv)); scriptenv.mailbox_autocreate = TRUE; scriptenv.default_mailbox = dst_mailbox; - scriptenv.namespaces = dst_ns; + scriptenv.user = mail_user; scriptenv.username = user; scriptenv.hostname = "host.example.com"; scriptenv.postmaster_address = "postmaster@example.com"; diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c index c459b69ac..149b5848e 100644 --- a/src/sieve-tools/sieve-test.c +++ b/src/sieve-tools/sieve-test.c @@ -328,7 +328,7 @@ int main(int argc, char **argv) /* Compose script environment */ memset(&scriptenv, 0, sizeof(scriptenv)); scriptenv.default_mailbox = "INBOX"; - scriptenv.namespaces = ns; + scriptenv.user = mail_user; scriptenv.username = user; scriptenv.hostname = "host.example.com"; scriptenv.postmaster_address = "postmaster@example.com"; diff --git a/src/testsuite/testsuite-mailstore.c b/src/testsuite/testsuite-mailstore.c index 1b6f9b6e6..ca5b95512 100644 --- a/src/testsuite/testsuite-mailstore.c +++ b/src/testsuite/testsuite-mailstore.c @@ -109,9 +109,9 @@ void testsuite_mailstore_reset(void) * Mailbox Access */ -struct mail_namespace *testsuite_mailstore_get_namespace(void) +struct mail_user *testsuite_mailstore_get_user(void) { - return testsuite_mailstore_user->namespaces; + return testsuite_mailstore_user; } bool testsuite_mailstore_mailbox_create @@ -168,6 +168,7 @@ static struct mail *testsuite_mailstore_open(const char *folder) box = mailbox_alloc(ns->list, folder, flags); if ( mailbox_open(box) < 0 ) { sieve_sys_error("testsuite: failed to open mailbox '%s'", folder); + mailbox_free(&box); return NULL; } @@ -175,6 +176,7 @@ static struct mail *testsuite_mailstore_open(const char *folder) if ( mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0 ) { sieve_sys_error("testsuite: failed to sync mailbox '%s'", folder); + mailbox_free(&box); return NULL; } diff --git a/src/testsuite/testsuite-mailstore.h b/src/testsuite/testsuite-mailstore.h index c45a27500..132cdd387 100644 --- a/src/testsuite/testsuite-mailstore.h +++ b/src/testsuite/testsuite-mailstore.h @@ -19,10 +19,10 @@ void testsuite_mailstore_deinit(void); void testsuite_mailstore_reset(void); /* - * Namespace + * User */ -struct mail_namespace *testsuite_mailstore_get_namespace(void); +struct mail_user *testsuite_mailstore_get_user(void); /* * Mailbox Access diff --git a/src/testsuite/testsuite-script.c b/src/testsuite/testsuite-script.c index f939ce4be..ddd1f7168 100644 --- a/src/testsuite/testsuite-script.c +++ b/src/testsuite/testsuite-script.c @@ -103,7 +103,7 @@ bool testsuite_script_run(const struct sieve_runtime_env *renv) scriptenv.smtp_close = NULL; scriptenv.duplicate_mark = NULL; scriptenv.duplicate_check = NULL; - scriptenv.namespaces = renv->scriptenv->namespaces; + scriptenv.user = renv->scriptenv->user; scriptenv.trace_stream = renv->scriptenv->trace_stream; scriptenv.trace_level = renv->scriptenv->trace_level; @@ -157,7 +157,6 @@ bool testsuite_script_multiscript /* Compose script execution environment */ memset(&scriptenv, 0, sizeof(scriptenv)); scriptenv.default_mailbox = "INBOX"; - scriptenv.namespaces = NULL; scriptenv.username = "user"; scriptenv.hostname = "host.example.com"; scriptenv.postmaster_address = "postmaster@example.com"; @@ -165,7 +164,7 @@ bool testsuite_script_multiscript scriptenv.smtp_close = NULL; scriptenv.duplicate_mark = NULL; scriptenv.duplicate_check = NULL; - scriptenv.namespaces = renv->scriptenv->namespaces; + scriptenv.user = renv->scriptenv->user; scriptenv.trace_stream = renv->scriptenv->trace_stream; /* Start execution */ diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c index 4964965a9..fd01722de 100644 --- a/src/testsuite/testsuite.c +++ b/src/testsuite/testsuite.c @@ -241,7 +241,7 @@ int main(int argc, char **argv) testsuite_message_init(master_service, user, mail_user_dovecot); memset(&scriptenv, 0, sizeof(scriptenv)); - scriptenv.namespaces = testsuite_mailstore_get_namespace(); + scriptenv.user = testsuite_mailstore_get_user(); scriptenv.default_mailbox = "INBOX"; scriptenv.hostname = "testsuite.example.com"; scriptenv.postmaster_address = "postmaster@example.com"; -- GitLab