diff --git a/.hgignore b/.hgignore index 724452b3b19da0b2a694daf39f1ce5da4209552f..87d0fafa5aeea084dc139702d1c3503fe6cfe815 100644 --- a/.hgignore +++ b/.hgignore @@ -47,6 +47,7 @@ Makefile.in *.svbin **/Makefile **/Makefile.in +**/.libs src/sieve-tools/sievec src/sieve-tools/sieved diff --git a/src/lib-sieve-tool/Makefile.am b/src/lib-sieve-tool/Makefile.am index ab965c5a52a2e64656845601f7b9e38716d801cd..575cffd6b4092c41b858d899601a8f349c4d8891 100644 --- a/src/lib-sieve-tool/Makefile.am +++ b/src/lib-sieve-tool/Makefile.am @@ -5,6 +5,8 @@ AM_CPPFLAGS = \ -I$(dovecot_incdir) \ -I$(dovecot_incdir)/src/lib \ -I$(dovecot_incdir)/src/lib-mail \ + -I$(dovecot_incdir)/src/lib-master \ + -I$(dovecot_incdir)/src/lib-settings \ -I$(dovecot_incdir)/src/lib-index \ -I$(dovecot_incdir)/src/lib-storage \ -I$(dovecot_incdir)/src/lib-storage/index \ diff --git a/src/lib-sieve-tool/mail-raw.c b/src/lib-sieve-tool/mail-raw.c index 7098eb1604d7f728f11a6b356b4e3915ef1b9e80..a46bd6fb9ce3c1862da63c3ba833bcd390f962fe 100644 --- a/src/lib-sieve-tool/mail-raw.c +++ b/src/lib-sieve-tool/mail-raw.c @@ -17,7 +17,9 @@ #include "mbox-from.h" #include "raw-storage.h" #include "mail-namespace.h" - +#include "master-service.h" +#include "master-service-settings.h" +#include "settings-parser.h" #include "mail-raw.h" #include <stdio.h> @@ -46,20 +48,23 @@ static const char *wanted_headers[] = { */ static struct mail_namespace *raw_ns; +static struct mail_namespace_settings raw_ns_set; static struct mail_user *raw_mail_user; +char *raw_tmp_prefix; + /* * Raw mail implementation */ static struct istream *create_raw_stream - (int fd, time_t *mtime_r, const char **sender) +(int fd, time_t *mtime_r, const char **sender) { struct istream *input, *input2, *input_list[2]; const unsigned char *data; size_t i, size; int ret, tz; - char *env_sender; + char *env_sender = NULL; *mtime_r = (time_t)-1; fd_set_nonblock(fd, FALSE); @@ -85,7 +90,7 @@ static struct istream *create_raw_stream } } - if (sender != NULL) { + if (env_sender != NULL && sender != NULL) { *sender = t_strdup(env_sender); } i_free(env_sender); @@ -99,8 +104,8 @@ static struct istream *create_raw_stream i_stream_unref(&input); input_list[0] = input2; input_list[1] = NULL; - input = i_stream_create_seekable(input_list, MAIL_MAX_MEMORY_BUFFER, - "/tmp/dovecot.sieve-tool."); + input = i_stream_create_seekable + (input_list, MAIL_MAX_MEMORY_BUFFER, raw_tmp_prefix); i_stream_unref(&input2); return input; } @@ -109,28 +114,41 @@ static struct istream *create_raw_stream * Init/Deinit */ -void mail_raw_init(const char *user) +void mail_raw_init +(struct master_service *service, const char *user, + struct mail_user *mail_user) { - const char *error; + const char *errstr; + void **sets; + + sets = master_service_settings_get_others(service); + + raw_mail_user = mail_user_alloc(user, sets[0]); + mail_user_set_home(raw_mail_user, "/"); + + if (mail_user_init(raw_mail_user, &errstr) < 0) + i_fatal("Raw user initialization failed: %s", errstr); + + memset(&raw_ns_set, 0, sizeof(raw_ns_set)); + raw_ns_set.location = "/tmp"; - raw_mail_user = mail_user_init(user); - mail_user_set_home(raw_mail_user, NULL); raw_ns = mail_namespaces_init_empty(raw_mail_user); raw_ns->flags |= NAMESPACE_FLAG_INTERNAL; - - if ( mail_storage_create(raw_ns, "raw", "/tmp", - MAIL_STORAGE_FLAG_FULL_FS_ACCESS, - FILE_LOCK_METHOD_FCNTL, &error) < 0 ) { - i_fatal("Couldn't create internal raw storage: %s", error); - } + raw_ns->set = &raw_ns_set; + + if (mail_storage_create(raw_ns, "raw", 0, &errstr) < 0) + i_fatal("Couldn't create internal raw storage: %s", errstr); + + raw_tmp_prefix = i_strdup(mail_user_get_temp_prefix(mail_user)); } void mail_raw_deinit(void) { + i_free(raw_tmp_prefix); + mail_user_unref(&raw_mail_user); } - /* * Open raw mail data */ @@ -175,8 +193,6 @@ static struct mail_raw *mail_raw_create } if ( mailbox_sync(mailr->box, 0, 0, NULL ) < 0) { - enum mail_error error; - i_fatal("Can't sync delivery mail: %s", mail_storage_get_last_error(raw_ns->storage, &error)); } diff --git a/src/lib-sieve-tool/mail-raw.h b/src/lib-sieve-tool/mail-raw.h index 693433720c17ae36d330489d3a26361eadd69ebe..0f2c23e86cbeea01544023138cdebceac1675b01 100644 --- a/src/lib-sieve-tool/mail-raw.h +++ b/src/lib-sieve-tool/mail-raw.h @@ -4,6 +4,9 @@ #ifndef __MAIL_RAW_H #define __MAIL_RAW_H +#include "lib.h" +#include "master-service.h" + struct mail_raw { pool_t pool; struct mail *mail; @@ -13,7 +16,9 @@ struct mail_raw { struct mailbox_transaction_context *trans; }; -void mail_raw_init(const char *user); +void mail_raw_init +(struct master_service *service, const char *user, + struct mail_user *mail_user); void mail_raw_deinit(void); struct mail_raw *mail_raw_open_file(const char *path); diff --git a/src/lib-sieve-tool/sieve-tool.c b/src/lib-sieve-tool/sieve-tool.c index e02054593c817a2885c966582931a6eb940723b3..bb4596fc1a1ed0e98ef14116dd5c8444a7e941c3 100644 --- a/src/lib-sieve-tool/sieve-tool.c +++ b/src/lib-sieve-tool/sieve-tool.c @@ -32,31 +32,38 @@ static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED) /* warn about being killed because of some signal, except SIGINT (^C) * which is too common at least while testing :) */ - if (si->si_signo != SIGINT) { - /* FIMXE: strange error for a command line tool */ + if (si->si_signo != SIGINT) { + /* FIXME: strange error for a command line tool */ i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)", si->si_signo, dec2str(si->si_pid), dec2str(si->si_uid), lib_signal_code_to_str(si->si_signo, si->si_code)); - } - io_loop_stop(current_ioloop); + } + io_loop_stop(current_ioloop); } /* * Initialization */ -void sieve_tool_init(void) +/* HACK */ +static bool _init_lib = FALSE; + +void sieve_tool_init(bool init_lib) { - lib_init(); + _init_lib = init_lib; - ioloop = io_loop_create(); + if ( _init_lib ) { + lib_init(); - lib_signals_init(); - lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL); - lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL); - lib_signals_ignore(SIGPIPE, TRUE); - lib_signals_ignore(SIGALRM, FALSE); + ioloop = io_loop_create(); + + lib_signals_init(); + lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL); + lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL); + lib_signals_ignore(SIGPIPE, TRUE); + lib_signals_ignore(SIGALRM, FALSE); + } if ( !sieve_init() ) i_fatal("failed to initialize sieve implementation\n"); @@ -65,13 +72,17 @@ void sieve_tool_init(void) void sieve_tool_deinit(void) { sieve_deinit(); + + if ( _init_lib ) { + lib_signals_deinit(); - lib_signals_deinit(); + io_loop_destroy(&ioloop); - io_loop_destroy(&ioloop); - lib_deinit(); + lib_deinit(); + } } + /* * Commonly needed functionality */ diff --git a/src/lib-sieve-tool/sieve-tool.h b/src/lib-sieve-tool/sieve-tool.h index fbcef92696beb07a1c1634636d58704566d7a08d..4c7dbd43e61c4f4fd7db4c73e040b7b9e52af179 100644 --- a/src/lib-sieve-tool/sieve-tool.h +++ b/src/lib-sieve-tool/sieve-tool.h @@ -10,7 +10,7 @@ * Initialization */ -void sieve_tool_init(void); +void sieve_tool_init(bool init_lib); void sieve_tool_deinit(void); /* diff --git a/src/lib-sieve/Makefile.am b/src/lib-sieve/Makefile.am index b7c2b210fb6f35a1ad335311bb03868feeef2ef3..366cf2910c25196371948be63765dfdc95e9e2ce 100644 --- a/src/lib-sieve/Makefile.am +++ b/src/lib-sieve/Makefile.am @@ -64,6 +64,7 @@ libsieve_la_SOURCES = \ rfc2822.c \ sieve-limits.c \ sieve-message.c \ + sieve-smtp.c \ sieve-lexer.c \ sieve-script.c \ sieve-ast.c \ @@ -100,6 +101,7 @@ noinst_HEADERS = \ sieve-common.h \ sieve-limits.h \ sieve-message.h \ + sieve-smtp.h \ sieve-lexer.h \ sieve-script.h \ sieve-script-private.h \ diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 1efff576c36179fac65a05100606b495604e6a46..bbb412aa0ca415fb4ed84212b687b1274eba387d 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -21,6 +21,7 @@ #include "sieve-interpreter.h" #include "sieve-code-dumper.h" #include "sieve-result.h" +#include "sieve-smtp.h" #include <stdio.h> @@ -292,7 +293,7 @@ static bool act_redirect_send int ret; /* Just to be sure */ - if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) { + if ( !sieve_smtp_available(senv) ) { sieve_result_warning(aenv, "redirect action has no means to send mail."); return TRUE; } @@ -301,7 +302,7 @@ static bool act_redirect_send return FALSE; /* Open SMTP transport */ - smtp_handle = senv->smtp_open(ctx->to_address, msgdata->return_path, &f); + smtp_handle = sieve_smtp_open(senv, ctx->to_address, msgdata->return_path, &f); /* Remove unwanted headers */ input = i_stream_create_header_filter @@ -325,7 +326,7 @@ static bool act_redirect_send i_stream_unref(&input); /* Close SMTP transport */ - if ( !senv->smtp_close(smtp_handle) ) { + if ( !sieve_smtp_close(senv, smtp_handle) ) { sieve_result_error(aenv, "failed to redirect message to <%s> " "(refer to server log for more information)", @@ -350,7 +351,7 @@ static bool act_redirect_commit NULL : t_strdup_printf("%s-%s", msgdata->id, ctx->to_address); if (dupeid != NULL) { /* Check whether we've seen this message before */ - if (senv->duplicate_check(dupeid, strlen(dupeid), senv->username)) { + if (sieve_action_duplicate_check(senv, dupeid, strlen(dupeid))) { sieve_result_log(aenv, "discarded duplicate forward to <%s>", str_sanitize(ctx->to_address, 128)); return TRUE; @@ -362,7 +363,7 @@ static bool act_redirect_commit /* Mark this message id as forwarded to the specified destination */ if (dupeid != NULL) { - senv->duplicate_mark(dupeid, strlen(dupeid), senv->username, + sieve_action_duplicate_mark(senv, dupeid, strlen(dupeid), ioloop_time + CMD_REDIRECT_DUPLICATE_KEEP); } diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index 62e351a6e1d69ee4155cd9d5adf348a4ace0b113..cbaf090754623a9db1f687d3d8b4b3892c51a3e1 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -34,6 +34,7 @@ #include "sieve-dump.h" #include "sieve-result.h" #include "sieve-message.h" +#include "sieve-smtp.h" /* * Forward declarations @@ -329,12 +330,12 @@ static bool act_reject_send int ret; /* Just to be sure */ - if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) { + if ( !sieve_smtp_available(senv) ) { sieve_result_warning(aenv, "reject action has no means to send mail"); return TRUE; } - smtp_handle = senv->smtp_open(msgdata->return_path, NULL, &f); + smtp_handle = sieve_smtp_open(senv, msgdata->return_path, NULL, &f); new_msgid = sieve_message_get_new_id(senv); boundary = t_strdup_printf("%s/%s", my_pid, senv->hostname); @@ -410,7 +411,7 @@ static bool act_reject_send fprintf(f, "\r\n\r\n--%s--\r\n", boundary); - if ( !senv->smtp_close(smtp_handle) ) { + if ( !sieve_smtp_close(senv, smtp_handle) ) { sieve_result_error(aenv, "failed to send rejection message to <%s> " "(refer to server log for more information)", diff --git a/src/lib-sieve/plugins/enotify/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/ntfy-mailto.c index aeb5560953eda52223d3c18d67dd7440e0172ad2..36ed896da3ca20c8766164ec33e559bd05321c5d 100644 --- a/src/lib-sieve/plugins/enotify/ntfy-mailto.c +++ b/src/lib-sieve/plugins/enotify/ntfy-mailto.c @@ -31,6 +31,7 @@ #include "sieve-ext-enotify.h" #include "sieve-address.h" #include "sieve-message.h" +#include "sieve-smtp.h" /* * Configuration @@ -919,7 +920,7 @@ static bool ntfy_mailto_send } /* Just to be sure */ - if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) { + if ( !sieve_smtp_available(senv) ) { sieve_enotify_warning(nlog, "notify mailto method has no means to send mail"); return TRUE; @@ -985,7 +986,8 @@ static bool ntfy_mailto_send const struct ntfy_mailto_header_field *headers; unsigned int h, hcount; - smtp_handle = senv->smtp_open(recipients[i].normalized, from_smtp, &f); + smtp_handle = sieve_smtp_open + (senv, recipients[i].normalized, from_smtp, &f); outmsgid = sieve_message_get_new_id(senv); rfc2822_header_field_write(f, "X-Sieve", SIEVE_IMPLEMENTATION); @@ -1048,7 +1050,7 @@ static bool ntfy_mailto_send fprintf(f, "Notification of new message.\r\n"); } - if ( senv->smtp_close(smtp_handle) ) { + if ( sieve_smtp_close(senv, smtp_handle) ) { sieve_enotify_log(nlog, "sent mail notification to <%s>", str_sanitize(recipients[i].normalized, 80)); diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 3b98abac9910625dc4c2392b7694d25c1c7d213c..81b5161eb62ab665e591c2ab916dd25130260fbf 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -25,6 +25,7 @@ #include "sieve-dump.h" #include "sieve-result.h" #include "sieve-message.h" +#include "sieve-smtp.h" #include "ext-vacation-common.h" @@ -869,14 +870,14 @@ static bool act_vacation_send /* Check smpt functions just to be sure */ - if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) { + if ( !sieve_smtp_available(senv) ) { sieve_result_warning(aenv, "vacation action has no means to send mail"); return TRUE; } /* Open smtp session */ - smtp_handle = senv->smtp_open(msgdata->return_path, NULL, &f); + smtp_handle = sieve_smtp_open(senv, msgdata->return_path, NULL, &f); outmsgid = sieve_message_get_new_id(senv); /* Produce a proper reply */ @@ -929,7 +930,7 @@ static bool act_vacation_send fprintf(f, "%s\r\n", ctx->reason); /* Close smtp session */ - if ( !senv->smtp_close(smtp_handle) ) { + if ( !sieve_smtp_close(senv, smtp_handle) ) { sieve_result_error(aenv, "failed to send vacation response to <%s> " "(refer to server log for more information)", @@ -985,10 +986,10 @@ static bool act_vacation_commit } /* Did whe respond to this user before? */ - if ( senv->duplicate_check != NULL ) { + if ( sieve_action_duplicate_check_available(senv) ) { act_vacation_hash(msgdata, ctx, dupl_hash); - if ( senv->duplicate_check(dupl_hash, sizeof(dupl_hash), senv->username) ) + if ( sieve_action_duplicate_check(senv, dupl_hash, sizeof(dupl_hash)) ) { sieve_result_log(aenv, "discarded duplicate vacation response to <%s>", str_sanitize(msgdata->return_path, 128)); @@ -1103,8 +1104,8 @@ static bool act_vacation_commit str_sanitize(msgdata->return_path, 128)); /* Mark as replied */ - if ( senv->duplicate_mark != NULL ) - senv->duplicate_mark(dupl_hash, sizeof(dupl_hash), senv->username, + sieve_action_duplicate_mark + (senv, dupl_hash, sizeof(dupl_hash), ioloop_time + ctx->days * (24 * 60 * 60)); return TRUE; diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index 2c5d141ce9d420d4e1991173adcbef07ff9723ec..bcb5374273dedf7944583201ecbea27b829bfcff 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -457,6 +457,35 @@ static void act_store_rollback mailbox_close(&trans->box); } +/* + * Action utility functions + */ + +bool sieve_action_duplicate_check_available +(const struct sieve_script_env *senv) +{ + return ( senv->duplicate_check != NULL && senv->duplicate_mark != NULL ); +} + +int sieve_action_duplicate_check +(const struct sieve_script_env *senv, const void *id, size_t id_size) +{ + if ( senv->duplicate_check == NULL || senv->duplicate_mark == NULL) + return 0; + + return senv->duplicate_check + (id, id_size, senv->username); +} +void sieve_action_duplicate_mark +(const struct sieve_script_env *senv, const void *id, size_t id_size, + time_t time) +{ + if ( senv->duplicate_check == NULL || senv->duplicate_mark == NULL) + return; + senv->duplicate_mark + (id, id_size, senv->username, time); +} + diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index c088ab58c42c846f5f69898ce0b2b18f037275f5..ef82f090fea936e56056cbcbabd0f5cc6ab59d8f 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -205,5 +205,17 @@ int sieve_act_store_add_to_result (const struct sieve_runtime_env *renv, struct sieve_side_effects_list *seffects, const char *folder, unsigned int source_line); - + +/* + * Action utility functions + */ + +bool sieve_action_duplicate_check_available + (const struct sieve_script_env *senv); +int sieve_action_duplicate_check + (const struct sieve_script_env *senv, const void *id, size_t id_size); +void sieve_action_duplicate_mark + (const struct sieve_script_env *senv, const void *id, size_t id_size, + time_t time); + #endif /* __SIEVE_ACTIONS_H */ diff --git a/src/lib-sieve/sieve-smtp.c b/src/lib-sieve/sieve-smtp.c new file mode 100644 index 0000000000000000000000000000000000000000..073f45dfc8a62c8c3bcebf300ee976950d3d5eba --- /dev/null +++ b/src/lib-sieve/sieve-smtp.c @@ -0,0 +1,32 @@ +#include "lib.h" + +#include "sieve-common.h" +#include "sieve-smtp.h" + + +bool sieve_smtp_available +(const struct sieve_script_env *senv) +{ + return ( senv->smtp_open != NULL && senv->smtp_close != NULL ); +} + +void *sieve_smtp_open +(const struct sieve_script_env *senv, const char *destination, + const char *return_path, FILE **file_r) +{ + if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) + return NULL; + + return senv->smtp_open + (senv->script_context, destination, return_path, file_r); +} + +bool sieve_smtp_close +(const struct sieve_script_env *senv, void *handle) +{ + if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) + return NULL; + + return senv->smtp_close(senv->script_context, handle); +} + diff --git a/src/lib-sieve/sieve-smtp.h b/src/lib-sieve/sieve-smtp.h new file mode 100644 index 0000000000000000000000000000000000000000..283167edadc367dc151932acea970e5d4715aa64 --- /dev/null +++ b/src/lib-sieve/sieve-smtp.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file + */ + + +#ifndef __SIEVE_SMTP_H +#define __SIEVE_SMTP_H + +#include "sieve-common.h" + +bool sieve_smtp_available + (const struct sieve_script_env *senv); + +void *sieve_smtp_open + (const struct sieve_script_env *senv, const char *destination, + const char *return_path, FILE **file_r); + +bool sieve_smtp_close + (const struct sieve_script_env *senv, void *handle); + +#endif /* __SIEVE_SMTP_H */ diff --git a/src/lib-sieve/sieve-types.h b/src/lib-sieve/sieve-types.h index 28c4abe768cbe5dac269cca5ea07f80facf1d234..eebeabf4ad46df0c17a77eb80965ef35d69dbd4a 100644 --- a/src/lib-sieve/sieve-types.h +++ b/src/lib-sieve/sieve-types.h @@ -50,18 +50,24 @@ struct sieve_script_env { const char *hostname; const char *postmaster_address; + /* External context data */ + + void *script_context; + /* Callbacks */ /* Interface for sending mail */ void *(*smtp_open) - (const char *destination, const char *return_path, FILE **file_r); - bool (*smtp_close)(void *handle); + (void *script_ctx, const char *destination, + const char *return_path, FILE **file_r); + bool (*smtp_close)(void *script_ctx, void *handle); /* Interface for marking and checking duplicates */ int (*duplicate_check) (const void *id, size_t id_size, const char *user); void (*duplicate_mark) - (const void *id, size_t id_size, const char *user, time_t time); + (const void *id, size_t id_size, const char *user, + time_t time); /* Execution status record */ struct sieve_exec_status *exec_status; diff --git a/src/plugins/lda-sieve/Makefile.am b/src/plugins/lda-sieve/Makefile.am index 994aafbe3ae4b9fbd4bb3adadd16d254310912f5..1c8a6418c04dffc20d5e390d4c1381aab240802a 100644 --- a/src/plugins/lda-sieve/Makefile.am +++ b/src/plugins/lda-sieve/Makefile.am @@ -5,7 +5,8 @@ AM_CPPFLAGS = \ -I$(dovecot_incdir)/src/lib-dict \ -I$(dovecot_incdir)/src/lib-mail \ -I$(dovecot_incdir)/src/lib-storage \ - -I$(dovecot_incdir)/src/deliver + -I$(dovecot_incdir)/src/lib-lda \ + -I$(dovecot_incdir)/src/lda lda_moduledir = $(moduledir)/lda diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c index 56526285798aba4d80e66e6cd9759d0a9bd5cbb9..7fdaf8e60002db41bd0ce31593e3fcf24690b02f 100644 --- a/src/plugins/lda-sieve/lda-sieve-plugin.c +++ b/src/plugins/lda-sieve/lda-sieve-plugin.c @@ -4,9 +4,12 @@ #include "lib.h" #include "array.h" #include "home-expand.h" -#include "deliver.h" +#include "mail-storage.h" +#include "mail-deliver.h" +#include "mail-user.h" #include "duplicate.h" #include "smtp-client.h" +#include "lda-settings.h" #include "sieve.h" @@ -37,13 +40,17 @@ static bool lda_sieve_debug = FALSE; * Mail transmission */ -static void *lda_sieve_smtp_open(const char *destination, +static void *lda_sieve_smtp_open +(void *script_ctx, const char *destination, const char *return_path, FILE **file_r) { - return (void *) smtp_client_open(destination, return_path, file_r); + return (void *) smtp_client_open + ((struct mail_deliver_context *) script_ctx, destination, + return_path, file_r); } -static bool lda_sieve_smtp_close(void *handle) +static bool lda_sieve_smtp_close +(void *script_ctx ATTR_UNUSED, void *handle) { struct smtp_client *smtp_client = (struct smtp_client *) handle; @@ -425,10 +432,9 @@ static int lda_sieve_multiscript_execute } static int lda_sieve_run -(struct mail_namespace *namespaces, struct mail *mail, const char *user_script, - const ARRAY_TYPE (const_string) *scripts_before, - const ARRAY_TYPE (const_string) *scripts_after, - const char *destaddr, const char *username, const char *mailbox, +(struct mail_deliver_context *mdctx, const char *user_script, + const ARRAY_TYPE (const_string) *scripts_before, + const ARRAY_TYPE (const_string) *scripts_after, struct mail_storage **storage_r) { ARRAY_TYPE (const_string) scripts; @@ -471,11 +477,11 @@ static int lda_sieve_run memset(&msgdata, 0, sizeof(msgdata)); - msgdata.mail = mail; - msgdata.return_path = deliver_get_return_address(mail); - msgdata.to_address = destaddr; - msgdata.auth_user = username; - (void)mail_get_first_header(mail, "Message-ID", &msgdata.id); + msgdata.mail = mdctx->src_mail; + msgdata.return_path = mail_deliver_get_return_address(mdctx); + msgdata.to_address = mdctx->dest_addr; + msgdata.auth_user = mdctx->dest_user->username; + (void)mail_get_first_header(msgdata.mail, "Message-ID", &msgdata.id); srctx.msgdata = &msgdata; @@ -483,17 +489,18 @@ static int lda_sieve_run memset(&scriptenv, 0, sizeof(scriptenv)); - scriptenv.default_mailbox = mailbox; - scriptenv.mailbox_autocreate = deliver_set->mailbox_autocreate; - scriptenv.mailbox_autosubscribe = deliver_set->mailbox_autosubscribe; - scriptenv.namespaces = namespaces; - scriptenv.username = username; - scriptenv.hostname = deliver_set->hostname; - scriptenv.postmaster_address = deliver_set->postmaster_address; + 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.username = mdctx->dest_user->username; + scriptenv.hostname = mdctx->set->hostname; + scriptenv.postmaster_address = mdctx->set->postmaster_address; scriptenv.smtp_open = lda_sieve_smtp_open; scriptenv.smtp_close = lda_sieve_smtp_close; scriptenv.duplicate_mark = duplicate_mark; scriptenv.duplicate_check = duplicate_check; + scriptenv.script_context = (void *) mdctx; scriptenv.exec_status = &estatus; srctx.scriptenv = &scriptenv; @@ -511,7 +518,7 @@ static int lda_sieve_run /* Record status */ - tried_default_save = estatus.tried_default_save; + mdctx->tried_default_save = estatus.tried_default_save; *storage_r = estatus.last_storage; /* Clean up */ @@ -524,8 +531,7 @@ static int lda_sieve_run } static int lda_sieve_deliver_mail -(struct mail_namespace *namespaces, struct mail_storage **storage_r, - struct mail *mail, const char *destaddr, const char *mailbox) +(struct mail_deliver_context *mdctx, struct mail_storage **storage_r) { const char *user_script, *sieve_before, *sieve_after; ARRAY_TYPE (const_string) scripts_before; @@ -593,8 +599,7 @@ static int lda_sieve_deliver_mail /* Run the script(s) */ ret = lda_sieve_run - (namespaces, mail, user_script, &scripts_before, &scripts_after, destaddr, - getenv("USER"), mailbox, storage_r); + (mdctx, user_script, &scripts_before, &scripts_after, storage_r); } } T_END; diff --git a/src/sieve-tools/Makefile.am b/src/sieve-tools/Makefile.am index ead0f8d3d2706198d7c7217d4230e8204af256c7..67f49be0c4e3359857a92647cbc196ebfa7d20ad 100644 --- a/src/sieve-tools/Makefile.am +++ b/src/sieve-tools/Makefile.am @@ -2,7 +2,7 @@ pkglibexecdir = $(libexecdir)/dovecot SUBDIRS = debug -bin_PROGRAMS = sievec sieved sieve-test sieve-filter +bin_PROGRAMS = sievec sieved sieve-test # sieve-filter AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib-sieve \ @@ -10,39 +10,37 @@ AM_CPPFLAGS = \ -I./debug \ -I$(dovecot_incdir) \ -I$(dovecot_incdir)/src/lib \ + -I$(dovecot_incdir)/src/lib-settings \ -I$(dovecot_incdir)/src/lib-mail \ + -I$(dovecot_incdir)/src/lib-imap \ -I$(dovecot_incdir)/src/lib-index \ + -I$(dovecot_incdir)/src/lib-master \ -I$(dovecot_incdir)/src/lib-storage \ - -I$(dovecot_incdir)/src/deliver + -I$(dovecot_incdir)/src/lib-storage/index \ + -I$(dovecot_incdir)/src/lib-storage/index/raw sievec_LDFLAGS = -export-dynamic sieved_LDFLAGS = -export-dynamic sieve_test_LDFLAGS = -export-dynamic -sieve_filter_LDFLAGS = -export-dynamic +# sieve_filter_LDFLAGS = -export-dynamic libs = \ $(top_srcdir)/src/lib-sieve/libsieve.la \ $(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \ - $(dovecot_incdir)/src/lib-storage/list/libstorage_list.a \ - $(dovecot_incdir)/src/lib-storage/register/libstorage-register.a \ - ./debug/libsieve_ext_debug.la \ - $(STORAGE_LIBS) - -ldadd = \ - $(libs) \ - $(LIBICONV) \ - $(RAND_LIBS) \ - $(MODULE_LIBS) - -sievec_LDADD = $(ldadd) -sieved_LDADD = $(ldadd) -sieve_test_LDADD = $(ldadd) -sieve_filter_LDADD = $(ldadd) + $(dovecot_incdir)/src/lib-storage/libdovecot-storage.la \ + $(dovecot_incdir)/src/lib-dovecot/libdovecot.la \ + ./debug/libsieve_ext_debug.la + + +sievec_LDADD = $(libs) +sieved_LDADD = $(libs) +sieve_test_LDADD = $(libs) +# sieve_filter_LDADD = $(libs) sievec_DEPENDENCIES = $(libs) sieved_DEPENDENCIES = $(libs) sieve_test_DEPENDENCIES = $(libs) -sieve_filter_DEPENDENCIES = $(libs) +# sieve_filter_DEPENDENCIES = $(libs) sievec_SOURCES = \ sievec.c @@ -53,7 +51,7 @@ sieved_SOURCES = \ sieve_test_SOURCES = \ sieve-test.c -sieve_filter_SOURCES = \ - sieve-filter.c +# sieve_filter_SOURCES = \ +# sieve-filter.c noinst_HEADERS = diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c index 08083d907419bf8ac2aa6808f1672802d7fb3c1d..98c3d97d3df540743cbfdd2e394e2a80e1c60fd9 100644 --- a/src/sieve-tools/sieve-test.c +++ b/src/sieve-tools/sieve-test.c @@ -2,11 +2,17 @@ */ #include "lib.h" +#include "lib-signals.h" +#include "ioloop.h" +#include "env-util.h" +#include "str.h" #include "ostream.h" #include "array.h" #include "mail-namespace.h" #include "mail-storage.h" -#include "env-util.h" +#include "master-service.h" +#include "master-service-settings.h" +#include "mail-storage-service.h" #include "sieve.h" #include "sieve-binary.h" @@ -22,6 +28,8 @@ #include <unistd.h> #include <fcntl.h> #include <pwd.h> +#include <sysexits.h> + /* * Configuration @@ -53,7 +61,8 @@ static void print_help(void) * Dummy SMTP session */ -static void *sieve_smtp_open(const char *destination, +static void *sieve_smtp_open +(void *script_ctx ATTR_UNUSED, const char *destination, const char *return_path, FILE **file_r) { i_info("sending message from <%s> to <%s>:", @@ -66,7 +75,8 @@ static void *sieve_smtp_open(const char *destination, return NULL; } -static bool sieve_smtp_close(void *handle ATTR_UNUSED) +static bool sieve_smtp_close +(void *script_ctx ATTR_UNUSED, void *handle ATTR_UNUSED) { printf("END MESSAGE\n\n"); return TRUE; @@ -96,14 +106,17 @@ static void duplicate_mark int main(int argc, char **argv) { + enum mail_storage_service_flags service_flags = 0; + struct master_service *service; + const char *getopt_str; + int c; ARRAY_DEFINE(scriptfiles, const char *); const char *scriptfile, *recipient, *sender, *mailbox, *dumpfile, *mailfile, *mailloc, *extensions; const char *user, *home; - int i; struct mail_raw *mailr; + struct mail_namespace_settings ns_set; struct mail_namespace *ns = NULL; - struct mail_user *mail_user = NULL; struct sieve_binary *main_sbin, *sbin = NULL; struct sieve_message_data msgdata; struct sieve_script_env scriptenv; @@ -114,89 +127,93 @@ int main(int argc, char **argv) bool trace = FALSE; int ret; - sieve_tool_init(); - + service = master_service_init("sieve-test", + MASTER_SERVICE_FLAG_STANDALONE, + argc, argv); + + sieve_tool_init(FALSE); + t_array_init(&scriptfiles, 16); + user = getenv("USER"); + /* Parse arguments */ scriptfile = recipient = sender = mailbox = dumpfile = mailfile = mailloc = extensions = NULL; - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-r") == 0) { - /* recipient address */ - i++; - if (i == argc) - i_fatal("Missing -r argument"); - recipient = argv[i]; - } else if (strcmp(argv[i], "-f") == 0) { - /* envelope sender */ - i++; - if (i == argc) - i_fatal("Missing -f argument"); - sender = argv[i]; - } else if (strcmp(argv[i], "-m") == 0) { + getopt_str = t_strconcat("r:f:m:d:l:x:s:ect", + master_service_getopt_string(), NULL); + while ((c = getopt(argc, argv, getopt_str)) > 0) { + switch (c) { + case 'r': + /* destination address */ + recipient = optarg; + break; + case 'f': + /* envelope sender address */ + sender = optarg; + break; + case 'm': /* default mailbox (keep box) */ - i++; - if (i == argc) - i_fatal("Missing -m argument"); - mailbox = argv[i]; - } else if (strcmp(argv[i], "-d") == 0) { + mailbox = optarg; + break; + case 'd': /* dump file */ - i++; - if (i == argc) - i_fatal("Missing -d argument"); - dumpfile = argv[i]; - } else if (strcmp(argv[i], "-l") == 0) { + dumpfile = optarg; + break; + case 'l': /* mail location */ - i++; - if (i == argc) - i_fatal("Missing -l argument"); - mailloc = argv[i]; - } else if (strcmp(argv[i], "-x") == 0) { - /* extensions */ - i++; - if (i == argc) - i_fatal("Missing -x argument"); - extensions = argv[i]; - } else if (strcmp(argv[i], "-s") == 0) { - const char *file; - + mailloc = optarg; + break; + case 'x': + /* mail location */ + extensions = optarg; + break; + case 's': /* scriptfile executed before main script */ - i++; - if (i == argc) - i_fatal("Missing -s argument"); - - file = t_strdup(argv[i]); - array_append(&scriptfiles, &file, 1); - } else if (strcmp(argv[i], "-c") == 0) { - /* force compile */ - force_compile = TRUE; - } else if (strcmp(argv[i], "-e") == 0) { - /* execute */ - execute = TRUE; -#ifdef SIEVE_RUNTIME_TRACE - } else if (strcmp(argv[i], "-t") == 0) { - /* runtime trace */ - trace = TRUE; -#endif - } else if ( scriptfile == NULL ) { - scriptfile = argv[i]; - } else if ( mailfile == NULL ) { - mailfile = argv[i]; - } else { - print_help(); - i_fatal("Unknown argument: %s", argv[i]); - } + { + const char *file; + + file = t_strdup(optarg); + array_append(&scriptfiles, &file, 1); + } + break; + + case 'e': + execute = TRUE; + break; + case 'c': + force_compile = TRUE; + break; + case 't': + trace = TRUE; + break; + default: + if (!master_service_parse_option(service, c, optarg)) { + print_help(); + i_fatal_status(EX_USAGE, + "Unknown argument: %c", c); + } + break; + } + } + + if ( optind < argc ) { + scriptfile = t_strdup(argv[optind++]); + } else { + print_help(); + i_fatal_status(EX_USAGE, "Missing <scriptfile> argument"); } - if ( scriptfile == NULL ) { + if ( optind < argc ) { + mailfile = t_strdup(argv[optind++]); + } else { print_help(); - i_fatal("Missing <scriptfile> argument"); + i_fatal_status(EX_USAGE, "Missing <mailfile> argument"); } - if ( mailfile == NULL ) { + if (optind != argc) { print_help(); - i_fatal("Missing <mailfile> argument"); + i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]); } if ( extensions != NULL ) { @@ -220,6 +237,10 @@ int main(int argc, char **argv) } if ( main_sbin != NULL ) { + struct mail_user *mail_user_dovecot = NULL; + struct mail_user *mail_user = NULL; + struct mail_storage_service_input input; + /* Dump script */ sieve_tool_dump_binary_to(main_sbin, dumpfile); @@ -227,29 +248,38 @@ int main(int argc, char **argv) home = getenv("HOME"); /* Initialize mail storages */ - mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL); - mail_storage_init(); - mail_storage_register_all(); - mailbox_list_register_all(); + //env_remove("HOME"); + env_put("DOVECONF_ENV=1"); + env_put(t_strdup_printf("MAIL=maildir:/tmp/dovecot-test-%s", user)); + + memset(&input, 0, sizeof(input)); + input.username = user; + mail_user_dovecot = mail_storage_service_init_user(service, &input, + NULL, service_flags); /* Obtain mail namespaces from -l argument */ if ( mailloc != NULL ) { - env_put(t_strdup_printf("NAMESPACE_1=%s", mailloc)); - env_put("NAMESPACE_1_INBOX=1"); - env_put("NAMESPACE_1_LIST=1"); - env_put("NAMESPACE_1_SEP=."); - env_put("NAMESPACE_1_SUBSCRIPTIONS=1"); + const char *errstr; - mail_user = mail_user_init(user); + mail_user = mail_user_alloc(user, mail_user_dovecot->unexpanded_set); mail_user_set_home(mail_user, home); - if (mail_namespaces_init(mail_user) < 0) - i_fatal("Namespace initialization failed"); - ns = mail_user->namespaces; + if (mail_user_init(mail_user, &errstr) < 0) + i_fatal("Test user initialization failed: %s", errstr); + + memset(&ns_set, 0, sizeof(ns_set)); + ns_set.location = mailloc; + + ns = mail_namespaces_init_empty(mail_user); + ns->flags |= NAMESPACE_FLAG_INTERNAL; + ns->set = &ns_set; } + if (master_service_set(service, "mail_full_filesystem_access=yes") < 0) + i_unreached(); + /* Initialize raw mail object */ - mail_raw_init(user); + mail_raw_init(service, user, mail_user_dovecot); mailr = mail_raw_open_file(mailfile); sieve_tool_get_envelope_data(mailr->mail, &recipient, &sender); @@ -388,13 +418,14 @@ int main(int argc, char **argv) mail_raw_close(mailr); mail_raw_deinit(); - /* De-initialize mail user object */ + /* De-initialize mail user objects */ if ( mail_user != NULL ) mail_user_unref(&mail_user); - /* De-initialize mail storages */ - mail_storage_deinit(); - mail_users_deinit(); + if ( mail_user_dovecot != NULL ) + mail_user_unref(&mail_user_dovecot); + + mail_storage_service_deinit_user(); } /* Cleanup error handler */ @@ -402,6 +433,8 @@ int main(int argc, char **argv) sieve_system_ehandler_reset(); sieve_tool_deinit(); + + master_service_deinit(&service); return 0; } diff --git a/src/sieve-tools/sievec.c b/src/sieve-tools/sievec.c index 9ba488ec2d2153373d565b92e3ff7523046677f1..b6bf4d1c8f881dbdb67db398f64931972a3789ba 100644 --- a/src/sieve-tools/sievec.c +++ b/src/sieve-tools/sievec.c @@ -41,7 +41,7 @@ int main(int argc, char **argv) { bool dump = FALSE; const char *scriptfile, *outfile, *extensions; - sieve_tool_init(); + sieve_tool_init(TRUE); scriptfile = outfile = extensions = NULL; for (i = 1; i < argc; i++) { diff --git a/src/sieve-tools/sieved.c b/src/sieve-tools/sieved.c index 33166797971f5ebbccd1d80ba51224ac5497aa0b..61d740275d4642d2ef22a714d37d4489c02a269c 100644 --- a/src/sieve-tools/sieved.c +++ b/src/sieve-tools/sieved.c @@ -38,7 +38,7 @@ int main(int argc, char **argv) { struct sieve_binary *sbin; const char *binfile, *outfile, *extensions; - sieve_tool_init(); + sieve_tool_init(TRUE); binfile = outfile = extensions = NULL; for (i = 1; i < argc; i++) { diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index 66050b5ab933435b06e9169442703a36eb0ccc60..c8bd6f5007d3057a9dbdc4a5d9c49c225f098fe4 100644 --- a/src/testsuite/Makefile.am +++ b/src/testsuite/Makefile.am @@ -1,30 +1,28 @@ noinst_PROGRAMS = testsuite AM_CPPFLAGS = \ - -I../lib-sieve \ - -I../lib-sieve-tool \ + -I$(top_srcdir)/src/lib-sieve \ + -I$(top_srcdir)/src/lib-sieve-tool \ -I$(dovecot_incdir) \ -I$(dovecot_incdir)/src/lib \ + -I$(dovecot_incdir)/src/lib-settings \ -I$(dovecot_incdir)/src/lib-mail \ + -I$(dovecot_incdir)/src/lib-imap \ -I$(dovecot_incdir)/src/lib-index \ - -I$(dovecot_incdir)/src/lib-storage + -I$(dovecot_incdir)/src/lib-master \ + -I$(dovecot_incdir)/src/lib-storage \ + -I$(dovecot_incdir)/src/lib-storage/index \ + -I$(dovecot_incdir)/src/lib-storage/index/raw testsuite_LDFLAGS = -export-dynamic libs = \ $(top_srcdir)/src/lib-sieve/libsieve.la \ $(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \ - $(dovecot_incdir)/src/lib-storage/list/libstorage_list.a \ - $(dovecot_incdir)/src/lib-storage/register/libstorage-register.a \ - $(STORAGE_LIBS) + $(dovecot_incdir)/src/lib-storage/libdovecot-storage.la \ + $(dovecot_incdir)/src/lib-dovecot/libdovecot.la -ldadd = \ - $(libs) \ - $(LIBICONV) \ - $(RAND_LIBS) \ - $(MODULE_LIBS) - -testsuite_LDADD = $(ldadd) +testsuite_LDADD = $(libs) testsuite_DEPENDENCIES = $(libs) commands = \ diff --git a/src/testsuite/testsuite-message.c b/src/testsuite/testsuite-message.c index 26a4cad69d4f843015876eedb51034a34e3dffa2..9488222dd9d7ad33db4579089f5b8137e3c54ae3 100644 --- a/src/testsuite/testsuite-message.c +++ b/src/testsuite/testsuite-message.c @@ -4,6 +4,7 @@ #include "lib.h" #include "str.h" #include "mail-storage.h" +#include "master-service.h" #include "mail-raw.h" @@ -69,7 +70,8 @@ static void _testsuite_message_set_data(struct mail *mail) (void)mail_get_first_header(mail, "Message-ID", &testsuite_msgdata.id); } -void testsuite_message_init(const char *user) +void testsuite_message_init +(struct master_service *service, const char *user, struct mail_user *mail_user) { message_pool = pool_alloconly_create("testsuite_message", 6096); @@ -77,7 +79,7 @@ void testsuite_message_init(const char *user) str_append(default_message, _default_message_data); testsuite_user = user; - mail_raw_init(user); + mail_raw_init(service, user, mail_user); _raw_message = mail_raw_open_data(default_message); _testsuite_message_set_data(_raw_message->mail); diff --git a/src/testsuite/testsuite-message.h b/src/testsuite/testsuite-message.h index 526c35389a515bc6dfa27cff25d333500b15c04d..ca869c75e896a0b326510c72e26cd4038cca895b 100644 --- a/src/testsuite/testsuite-message.h +++ b/src/testsuite/testsuite-message.h @@ -4,11 +4,15 @@ #ifndef __TESTSUITE_MESSAGE_H #define __TESTSUITE_MESSAGE_H +#include "lib.h" +#include "master-service.h" + #include "sieve-common.h" extern struct sieve_message_data testsuite_msgdata; -void testsuite_message_init(const char *user); +void testsuite_message_init +(struct master_service *service, const char *user, struct mail_user *mail_user); void testsuite_message_deinit(void); void testsuite_message_set_string diff --git a/src/testsuite/testsuite-smtp.c b/src/testsuite/testsuite-smtp.c index 0f26c62ba384d7f19d2b26dde57fd6055a6a1b64..18eff1ca8c7baa0551de3b2690a88d245e0785a9 100644 --- a/src/testsuite/testsuite-smtp.c +++ b/src/testsuite/testsuite-smtp.c @@ -72,7 +72,8 @@ struct testsuite_smtp { }; void *testsuite_smtp_open - (const char *destination, const char *return_path, FILE **file_r) +(void *script_ctx ATTR_UNUSED, const char *destination, + const char *return_path, FILE **file_r) { struct testsuite_smtp_message smtp_msg; struct testsuite_smtp *smtp; @@ -97,7 +98,8 @@ void *testsuite_smtp_open return (void *) smtp; } -bool testsuite_smtp_close(void *handle) +bool testsuite_smtp_close +(void *script_ctx ATTR_UNUSED, void *handle) { struct testsuite_smtp *smtp = (struct testsuite_smtp *) handle; diff --git a/src/testsuite/testsuite-smtp.h b/src/testsuite/testsuite-smtp.h index f1e7f38a1d9015e779a6e6885937a3fb4621a225..9315c0ec778e0e89a1de0fd5af2fd49b8cd4ac53 100644 --- a/src/testsuite/testsuite-smtp.h +++ b/src/testsuite/testsuite-smtp.h @@ -13,8 +13,10 @@ void testsuite_smtp_reset(void); */ void *testsuite_smtp_open - (const char *destination, const char *return_path, FILE **file_r); -bool testsuite_smtp_close(void *handle); + (void *script_ctx, const char *destination, const char *return_path, + FILE **file_r); +bool testsuite_smtp_close + (void *script_ctx, void *handle); /* * Access diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c index 933399fe1189f517cd37cbdd759a1b1450ab9fbc..c923d116faa06ab655ac83b3ca39161e06acf76d 100644 --- a/src/testsuite/testsuite.c +++ b/src/testsuite/testsuite.c @@ -4,11 +4,14 @@ #include "lib.h" #include "lib-signals.h" #include "ioloop.h" +#include "env-util.h" #include "ostream.h" #include "hostpid.h" #include "mail-storage.h" #include "mail-namespace.h" -#include "env-util.h" +#include "master-service.h" +#include "master-service-settings.h" +#include "mail-storage-service.h" #include "sieve.h" #include "sieve-extensions.h" @@ -30,6 +33,7 @@ #include <unistd.h> #include <fcntl.h> #include <pwd.h> +#include <sysexits.h> /* * Configuration @@ -44,7 +48,7 @@ static void testsuite_tool_init(void) { - sieve_tool_init(); + sieve_tool_init(FALSE); sieve_extensions_set_string(NULL); @@ -99,47 +103,77 @@ static int testsuite_run return ret; } +/* IEW.. YUCK.. and so forth.. */ +static const char *_get_cwd(void) +{ + static char cwd[PATH_MAX]; + const char *result; + + result = t_strdup(getcwd(cwd, sizeof(cwd))); + + return result; +} + int main(int argc, char **argv) { + enum mail_storage_service_flags service_flags = 0; + struct master_service *service; + const char *getopt_str; + int c; const char *scriptfile, *dumpfile; const char *user; - int i, ret; struct sieve_binary *sbin; const char *sieve_dir; bool trace = FALSE; + int ret; + + service = master_service_init("testsuite", + MASTER_SERVICE_FLAG_STANDALONE, + argc, argv); + + /* Initialize testsuite */ + testsuite_tool_init(); + + user = getenv("USER"); /* Parse arguments */ scriptfile = dumpfile = NULL; - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-d") == 0) { - /* dump file */ - i++; - if (i == argc) - i_fatal("Missing -d argument"); - dumpfile = argv[i]; -#ifdef SIEVE_RUNTIME_TRACE - } else if (strcmp(argv[i], "-t") == 0) { - /* runtime trace */ + + getopt_str = t_strconcat("d:t", + master_service_getopt_string(), NULL); + while ((c = getopt(argc, argv, getopt_str)) > 0) { + switch (c) { + case 'd': + /* destination address */ + dumpfile = optarg; + break; + case 't': trace = TRUE; -#endif - } else if ( scriptfile == NULL ) { - scriptfile = argv[i]; - } else { - print_help(); - i_fatal("Unknown argument: %s", argv[i]); + break; + default: + if (!master_service_parse_option(service, c, optarg)) { + print_help(); + i_fatal_status(EX_USAGE, + "Unknown argument: %c", c); + } + break; } } - - if ( scriptfile == NULL ) { + + if ( optind < argc ) { + scriptfile = t_strdup(argv[optind++]); + } else { print_help(); - i_fatal("Missing <scriptfile> argument"); + i_fatal_status(EX_USAGE, "Missing <scriptfile> argument"); } + + if (optind != argc) { + print_help(); + i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]); + } printf("Test case: %s:\n\n", scriptfile); - /* Initialize testsuite */ - testsuite_tool_init(); - /* Initialize environment */ sieve_dir = strrchr(scriptfile, '/'); if ( sieve_dir == NULL ) @@ -153,21 +187,29 @@ int main(int argc, char **argv) /* Compile sieve script */ if ( (sbin = sieve_tool_script_compile(scriptfile, NULL)) != NULL ) { + struct mail_storage_service_input input; struct sieve_script_env scriptenv; struct sieve_error_handler *ehandler; + struct mail_user *mail_user; /* Dump script */ sieve_tool_dump_binary_to(sbin, dumpfile); - /* Initialize mail storages */ - mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL); - mail_storage_init(); - mail_storage_register_all(); - mailbox_list_register_all(); - - /* Initialize message environment */ + /* Initialize mail user */ user = sieve_tool_get_user(); - testsuite_message_init(user); + env_put("DOVECONF_ENV=1"); + env_put(t_strdup_printf("HOME=%s", _get_cwd())); + env_put(t_strdup_printf("MAIL=maildir:/tmp/dovecot-test-%s", user)); + + memset(&input, 0, sizeof(input)); + input.username = user; + mail_user = mail_storage_service_init_user + (service, &input, NULL, service_flags); + + if (master_service_set(service, "mail_full_filesystem_access=yes") < 0) + i_unreached(); + + testsuite_message_init(service, user, mail_user); memset(&scriptenv, 0, sizeof(scriptenv)); scriptenv.default_mailbox = "INBOX"; @@ -204,9 +246,11 @@ int main(int argc, char **argv) /* De-initialize message environment */ testsuite_message_deinit(); - /* De-initialize mail storages */ - mail_storage_deinit(); - mail_users_deinit(); + /* De-initialize mail user */ + if ( mail_user != NULL ) + mail_user_unref(&mail_user); + + mail_storage_service_deinit_user(); } else { testsuite_testcase_fail("failed to compile testcase script"); } @@ -214,5 +258,7 @@ int main(int argc, char **argv) /* De-initialize testsuite */ testsuite_tool_deinit(); + master_service_deinit(&service); + return testsuite_testcase_result(); }