diff --git a/src/lib-sieve-tool/sieve-tool.c b/src/lib-sieve-tool/sieve-tool.c index 86ea2835e815ae72dada99013a14ae70965b0a12..ef5659071a18f75bfd222b055b035f48560c51dc 100644 --- a/src/lib-sieve-tool/sieve-tool.c +++ b/src/lib-sieve-tool/sieve-tool.c @@ -9,6 +9,7 @@ #include "hostpid.h" #include "dict.h" #include "mail-storage.h" +#include "mail-user.h" #include "sieve.h" #include "sieve-plugins.h" @@ -25,8 +26,6 @@ * Global state */ -static struct ioloop *ioloop; - /* Sieve instance */ struct sieve_instance *sieve_instance; @@ -36,15 +35,29 @@ struct sieve_instance *sieve_instance; */ const char *sieve_tool_get_setting -(void *context ATTR_UNUSED, const char *identifier) +(void *context, const char *identifier) { - return getenv(t_str_ucase(identifier)); + struct mail_user *mail_user = (struct mail_user *) context; + + if ( mail_user == NULL ) + return NULL; + + return mail_user_plugin_getenv(mail_user, identifier); } const char *sieve_tool_get_homedir -(void *context ATTR_UNUSED) +(void *context) { - return getenv("HOME"); + struct mail_user *mail_user = (struct mail_user *) context; + const char *home = NULL; + + if ( mail_user == NULL ) + return NULL; + + if ( mail_user_get_home(mail_user, &home) <= 0 ) + return NULL; + + return home; } const struct sieve_environment sieve_tool_sieve_env = { @@ -52,54 +65,16 @@ const struct sieve_environment sieve_tool_sieve_env = { sieve_tool_get_setting }; -/* - * Signal handlers - */ - -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) { - /* 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); -} - /* * Initialization */ -/* HACK */ -static bool _init_lib = FALSE; - -void sieve_tool_init(bool init_lib) -{ - _init_lib = init_lib; - - if ( _init_lib ) { - lib_init(); - - 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); - } -} - -void sieve_tool_sieve_init(const struct sieve_environment *env, bool debug) +void sieve_tool_init +(const struct sieve_environment *env, void *context, bool debug) { if ( env == NULL ) env = &sieve_tool_sieve_env; - if ( (sieve_instance=sieve_init(env, NULL, debug)) == NULL ) + if ( (sieve_instance=sieve_init(env, context, debug)) == NULL ) i_fatal("failed to initialize sieve implementation\n"); } @@ -107,13 +82,6 @@ void sieve_tool_deinit(void) { sieve_deinit(&sieve_instance); - if ( _init_lib ) { - lib_signals_deinit(); - - io_loop_destroy(&ioloop); - - lib_deinit(); - } } @@ -201,7 +169,7 @@ struct sieve_binary *sieve_tool_script_compile sieve_error_handler_accept_infolog(ehandler, TRUE); if ( (sbin = sieve_compile(sieve_instance, filename, name, ehandler)) == NULL ) - i_error("failed to compile sieve script '%s'\n", filename); + i_error("failed to compile sieve script '%s'", filename); sieve_error_handler_unref(&ehandler); @@ -218,7 +186,7 @@ struct sieve_binary *sieve_tool_script_open(const char *filename) if ( (sbin = sieve_open(sieve_instance, filename, NULL, ehandler, NULL)) == NULL ) { sieve_error_handler_unref(&ehandler); - i_fatal("Failed to compile sieve script\n"); + i_fatal("Failed to compile sieve script"); } sieve_error_handler_unref(&ehandler); diff --git a/src/lib-sieve-tool/sieve-tool.h b/src/lib-sieve-tool/sieve-tool.h index 3e3e0bb56a62923ba2331b58f5d1a878013f0ba2..4d95bb3f6d342ab16df870b8a7ea3b52171feab2 100644 --- a/src/lib-sieve-tool/sieve-tool.h +++ b/src/lib-sieve-tool/sieve-tool.h @@ -23,8 +23,8 @@ extern const struct sieve_environment sieve_tool_env; * Initialization */ -void sieve_tool_init(bool init_lib); -void sieve_tool_sieve_init(const struct sieve_environment *env, bool debug); +void sieve_tool_init + (const struct sieve_environment *env, void *context, bool debug); void sieve_tool_deinit(void); /* diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index 12716f6ff769f418606ffe9eb92d23642ef0ff2f..1832dc9a74bbfb61846ad28721dd480aa36dcaa2 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -5,6 +5,7 @@ #include "compat.h" #include "unichar.h" #include "array.h" +#include "abspath.h" #include "istream.h" #include "eacces-error.h" @@ -163,9 +164,11 @@ struct sieve_script *sieve_script_init if ( (ret=lstat(path, &st)) < 0 ) { switch ( errno ) { case ENOENT: - if ( exists_r == NULL ) + if ( exists_r == NULL ) { sieve_error(ehandler, basename, "sieve script does not exist"); - else + if ( svinst->debug ) + sieve_sys_debug("script file %s not found", t_abspath(path)); + } else *exists_r = FALSE; break; case EACCES: diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c index 149b5848e9f87f85ccdf5b7f393bb653e9bc6203..3207791c0c0ff47068d25987a22c89247adf4501 100644 --- a/src/sieve-tools/sieve-test.c +++ b/src/sieve-tools/sieve-test.c @@ -103,7 +103,12 @@ static void duplicate_mark int main(int argc, char **argv) { - enum mail_storage_service_flags service_flags = 0; + enum master_service_flags service_flags = + MASTER_SERVICE_FLAG_STANDALONE | + MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; + enum mail_storage_service_flags storage_service_flags = + MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR | + MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT; struct mail_storage_service_ctx *storage_service; struct mail_storage_service_user *service_user; struct mail_storage_service_input service_input; @@ -111,8 +116,8 @@ int main(int argc, char **argv) ARRAY_TYPE (const_string) scriptfiles; ARRAY_TYPE (const_string) plugins; const char *scriptfile, *recipient, *sender, *mailbox, *dumpfile, *mailfile, - *mailloc, *extensions; - const char *user, *home, *errstr; + *mailloc, *extensions, *username; + const char *errstr; struct mail_raw *mailr; struct mail_namespace_settings ns_set; struct mail_namespace *ns = NULL; @@ -128,18 +133,15 @@ int main(int argc, char **argv) int ret, c; master_service = master_service_init("sieve-test", - MASTER_SERVICE_FLAG_STANDALONE, &argc, &argv, "r:f:m:d:l:x:s:P:eCtD"); - - sieve_tool_init(FALSE); + service_flags, &argc, &argv, "r:f:m:d:l:x:s:P:eCtD"); t_array_init(&scriptfiles, 16); t_array_init(&plugins, 4); - - user = getenv("USER"); /* Parse arguments */ scriptfile = recipient = sender = mailbox = dumpfile = mailfile = mailloc = extensions = NULL; + username = getenv("USER"); while ((c = master_getopt(master_service)) > 0) { switch (c) { case 'r': @@ -166,6 +168,11 @@ int main(int argc, char **argv) /* extensions */ extensions = optarg; break; + case 'u': + storage_service_flags |= + MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; + username = optarg; + break; case 's': /* scriptfile executed before main script */ { @@ -204,14 +211,14 @@ int main(int argc, char **argv) } if ( optind < argc ) { - scriptfile = t_strdup(argv[optind++]); + scriptfile = argv[optind++]; } else { print_help(); i_fatal_status(EX_USAGE, "Missing <script-file> argument"); } if ( optind < argc ) { - mailfile = t_strdup(argv[optind++]); + mailfile = argv[optind++]; } else { print_help(); i_fatal_status(EX_USAGE, "Missing <mail-file> argument"); @@ -222,7 +229,22 @@ int main(int argc, char **argv) i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]); } - sieve_tool_sieve_init(NULL, debug); + master_service_init_finish(master_service); + + memset(&service_input, 0, sizeof(service_input)); + service_input.module = "sieve-test"; + service_input.service = "sieve-test"; + service_input.username = username; + + storage_service = mail_storage_service_init + (master_service, NULL, storage_service_flags); + if (mail_storage_service_lookup_next(storage_service, &service_input, + &service_user, &mail_user_dovecot, &errstr) <= 0) + i_fatal("%s", errstr); + + /* Initialize Sieve */ + + sieve_tool_init(NULL, (void *) mail_user_dovecot, debug); if ( array_count(&plugins) > 0 ) { sieve_tool_load_plugins(&plugins); @@ -234,27 +256,6 @@ int main(int argc, char **argv) /* Register tool-specific extensions */ (void) sieve_extension_register(sieve_instance, &debug_extension, TRUE); - - user = sieve_tool_get_user(); - home = getenv("HOME"); - - /* Initialize mail storages */ - //env_remove("HOME"); - env_put("DOVECONF_ENV=1"); - env_put(t_strdup_printf("MAIL=maildir:/tmp/dovecot-test-%s", user)); - - master_service_init_finish(master_service); - - memset(&service_input, 0, sizeof(service_input)); - service_input.module = "sieve-test"; - service_input.service = "sieve-test"; - service_input.username = user; - - storage_service = mail_storage_service_init - (master_service, NULL, service_flags); - if (mail_storage_service_lookup_next(storage_service, &service_input, - &service_user, &mail_user_dovecot, &errstr) <= 0) - i_fatal("%s", errstr); /* Create error handler */ ehandler = sieve_stderr_ehandler_create(0); @@ -280,11 +281,15 @@ int main(int argc, char **argv) /* Obtain mail namespaces from -l argument */ if ( mailloc != NULL ) { - const char *errstr; + const char *home, *errstr; mail_user = mail_user_alloc - (user, mail_user_dovecot->set_info, mail_user_dovecot->unexpanded_set); - mail_user_set_home(mail_user, home); + (username, mail_user_dovecot->set_info, mail_user_dovecot->unexpanded_set); + + if ( mail_user_get_home(mail_user_dovecot, &home) > 0 || + (home=getenv("HOME")) != NULL ) { + mail_user_set_home(mail_user, home); + } if ( mail_user_init(mail_user, &errstr) < 0 ) i_fatal("Test user initialization failed: %s", errstr); @@ -305,7 +310,7 @@ int main(int argc, char **argv) i_unreached(); /* Initialize raw mail object */ - mail_raw_init(master_service, user, mail_user_dovecot); + mail_raw_init(master_service, username, mail_user_dovecot); mailr = mail_raw_open_file(mailfile); sieve_tool_get_envelope_data(mailr->mail, &recipient, &sender); @@ -318,7 +323,7 @@ int main(int argc, char **argv) msgdata.mail = mailr->mail; msgdata.return_path = sender; msgdata.to_address = recipient; - msgdata.auth_user = user; + msgdata.auth_user = username; (void)mail_get_first_header(mailr->mail, "Message-ID", &msgdata.id); /* Create stream for test and trace output */ @@ -328,8 +333,8 @@ int main(int argc, char **argv) /* Compose script environment */ memset(&scriptenv, 0, sizeof(scriptenv)); scriptenv.default_mailbox = "INBOX"; - scriptenv.user = mail_user; - scriptenv.username = user; + scriptenv.user = mail_user == NULL ? mail_user_dovecot : mail_user; + scriptenv.username = username; scriptenv.hostname = "host.example.com"; scriptenv.postmaster_address = "postmaster@example.com"; scriptenv.smtp_open = sieve_smtp_open; @@ -457,9 +462,6 @@ int main(int argc, char **argv) if ( mail_user != NULL ) mail_user_unref(&mail_user); } - - if ( mail_user_dovecot != NULL ) - mail_user_unref(&mail_user_dovecot); /* Cleanup error handler */ sieve_error_handler_unref(&ehandler); @@ -467,6 +469,9 @@ int main(int argc, char **argv) sieve_tool_deinit(); + if ( mail_user_dovecot != NULL ) + mail_user_unref(&mail_user_dovecot); + mail_storage_service_user_free(&service_user); mail_storage_service_deinit(&storage_service); master_service_deinit(&master_service); diff --git a/src/sieve-tools/sievec.c b/src/sieve-tools/sievec.c index 993fec5b5738e65d73f1107c1cfcdca687ec7a6e..a7ea65c038e4c6da0577b73dfb09afef7ea56d08 100644 --- a/src/sieve-tools/sievec.c +++ b/src/sieve-tools/sievec.c @@ -3,6 +3,9 @@ #include "lib.h" #include "array.h" +#include "master-service.h" +#include "master-service-settings.h" +#include "mail-storage-service.h" #include "sieve.h" #include "sieve-extensions.h" @@ -39,62 +42,87 @@ static void print_help(void) int main(int argc, char **argv) { + enum master_service_flags service_flags = + MASTER_SERVICE_FLAG_STANDALONE | + MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; + enum mail_storage_service_flags storage_service_flags = + MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR | + MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT; + struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_user *service_user; + struct mail_storage_service_input service_input; + struct mail_user *mail_user_dovecot = NULL; ARRAY_TYPE(const_string) plugins; - int i; struct stat st; struct sieve_binary *sbin; bool dump = FALSE; - const char *scriptfile, *outfile, *extensions; + const char *scriptfile, *outfile, *extensions, *username; + const char *errstr; int exit_status = EXIT_SUCCESS; + int c; - sieve_tool_init(TRUE); + master_service = master_service_init("sievec", + service_flags, &argc, &argv, "dx:P:"); t_array_init(&plugins, 4); scriptfile = outfile = extensions = NULL; - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-d") == 0) { + username = getenv("USER"); + while ((c = master_getopt(master_service)) > 0) { + switch (c) { + case 'd': /* dump file */ dump = TRUE; - } else if (strcmp(argv[i], "-x") == 0) { + break; + case 'x': /* extensions */ - i++; - if (i == argc) { - print_help(); - i_fatal_status(EX_USAGE, "Missing -x argument"); + extensions = optarg; + break; + case 'P': + /* Plugin */ + { + const char *plugin; + + plugin = t_strdup(optarg); + array_append(&plugins, &plugin, 1); } - extensions = argv[i]; - } else if (strcmp(argv[i], "-P") == 0) { - const char *plugin; - - /* scriptfile executed before main script */ - i++; - if (i == argc) { - print_help(); - i_fatal_status(EX_USAGE, "Missing -P argument"); - } - - plugin = t_strdup(argv[i]); - array_append(&plugins, &plugin, 1); - } else if ( scriptfile == NULL ) { - scriptfile = argv[i]; - } else if ( outfile == NULL ) { - outfile = argv[i]; - } else { + break; + default: print_help(); - i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[i]); + i_fatal_status(EX_USAGE, "Unknown argument: %c", c); + break; } } - - if ( scriptfile == NULL ) { + + if ( optind < argc ) { + scriptfile = argv[optind++]; + } else { print_help(); i_fatal_status(EX_USAGE, "Missing <script-file> argument"); } - - if ( outfile == NULL && dump ) - outfile = "-"; - sieve_tool_sieve_init(NULL, FALSE); + if ( optind < argc ) { + outfile = argv[optind++]; + } else if ( dump ) { + outfile = "-"; + } + + master_service_init_finish(master_service); + + memset(&service_input, 0, sizeof(service_input)); + service_input.module = "sievec"; + service_input.service = "sievec"; + service_input.username = username; + + storage_service = mail_storage_service_init + (master_service, NULL, storage_service_flags); + if (mail_storage_service_lookup_next(storage_service, &service_input, + &service_user, &mail_user_dovecot, &errstr) <= 0) + i_fatal("%s", errstr); + + /* Initialize Sieve */ + + sieve_tool_init(NULL, (void *) mail_user_dovecot, FALSE); if ( array_count(&plugins) > 0 ) { sieve_tool_load_plugins(&plugins); @@ -178,5 +206,12 @@ int main(int argc, char **argv) sieve_tool_deinit(); + if ( mail_user_dovecot != NULL ) + mail_user_unref(&mail_user_dovecot); + + mail_storage_service_user_free(&service_user); + mail_storage_service_deinit(&storage_service); + master_service_deinit(&master_service); + return exit_status; } diff --git a/src/sieve-tools/sieved.c b/src/sieve-tools/sieved.c index 86581d7b4eff557b37ecdc8b06dcfd3e5807e694..e3f3cbf2049fac433e65a2a7a51867ebaaf99221 100644 --- a/src/sieve-tools/sieved.c +++ b/src/sieve-tools/sieved.c @@ -3,6 +3,9 @@ #include "lib.h" #include "array.h" +#include "master-service.h" +#include "master-service-settings.h" +#include "mail-storage-service.h" #include "sieve.h" #include "sieve-extensions.h" @@ -37,54 +40,81 @@ static void print_help(void) int main(int argc, char **argv) { + enum master_service_flags service_flags = + MASTER_SERVICE_FLAG_STANDALONE | + MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; + enum mail_storage_service_flags storage_service_flags = + MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR | + MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT; + struct mail_storage_service_ctx *storage_service; + struct mail_storage_service_user *service_user; + struct mail_storage_service_input service_input; + struct mail_user *mail_user_dovecot = NULL; ARRAY_TYPE(const_string) plugins; - int i; struct sieve_binary *sbin; - const char *binfile, *outfile, *extensions; + const char *binfile, *outfile, *extensions, *username; + const char *errstr; int exit_status = EXIT_SUCCESS; - - sieve_tool_init(TRUE); + int c; + master_service = master_service_init("sieved", + service_flags, &argc, &argv, "x:P:"); + t_array_init(&plugins, 4); binfile = outfile = extensions = NULL; - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-x") == 0) { + username = getenv("USER"); + while ((c = master_getopt(master_service)) > 0) { + switch (c) { + case 'x': /* extensions */ - i++; - if (i == argc) { - print_help(); - i_fatal_status(EX_USAGE, "Missing -x argument"); + extensions = optarg; + break; + case 'P': + /* Plugin */ + { + const char *plugin; + + plugin = t_strdup(optarg); + array_append(&plugins, &plugin, 1); } - extensions = argv[i]; - } else if (strcmp(argv[i], "-P") == 0) { - const char *plugin; - - /* scriptfile executed before main script */ - i++; - if (i == argc) { - print_help(); - i_fatal_status(EX_USAGE, "Missing -P argument"); - } - - plugin = t_strdup(argv[i]); - array_append(&plugins, &plugin, 1); - } else if ( binfile == NULL ) { - binfile = argv[i]; - } else if ( outfile == NULL ) { - outfile = argv[i]; - } else { + break; + default: print_help(); - i_fatal_status(EX_USAGE, "unknown argument: %s", argv[i]); + i_fatal_status(EX_USAGE, "Unknown argument: %c", c); + break; } } - - if ( binfile == NULL ) { + + if ( optind < argc ) { + binfile = argv[optind++]; + } else { print_help(); - i_fatal_status(EX_USAGE, "missing <sieve-binary> argument"); + i_fatal_status(EX_USAGE, "Missing <script-file> argument"); } - sieve_tool_sieve_init(NULL, FALSE); + if ( optind < argc ) { + outfile = argv[optind++]; + } + + /* Initialize Service */ + + master_service_init_finish(master_service); + + memset(&service_input, 0, sizeof(service_input)); + service_input.module = "sieved"; + service_input.service = "sieved"; + service_input.username = username; + + storage_service = mail_storage_service_init + (master_service, NULL, storage_service_flags); + if (mail_storage_service_lookup_next(storage_service, &service_input, + &service_user, &mail_user_dovecot, &errstr) <= 0) + i_fatal("%s", errstr); + + /* Initialize Sieve */ + + sieve_tool_init(NULL, (void *) mail_user_dovecot, FALSE); if ( array_count(&plugins) > 0 ) { sieve_tool_load_plugins(&plugins); @@ -110,6 +140,13 @@ int main(int argc, char **argv) sieve_tool_deinit(); + if ( mail_user_dovecot != NULL ) + mail_user_unref(&mail_user_dovecot); + + mail_storage_service_user_free(&service_user); + mail_storage_service_deinit(&storage_service); + master_service_deinit(&master_service); + return exit_status; } diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c index fd01722deea6c6a3132d40d83b9018ab16387af8..fce289d5ed4d287b80a502351d998105679316ed 100644 --- a/src/testsuite/testsuite.c +++ b/src/testsuite/testsuite.c @@ -123,8 +123,6 @@ int main(int argc, char **argv) user = getenv("USER"); - sieve_tool_init(FALSE); - t_array_init(&plugins, 4); /* Parse arguments */ @@ -202,7 +200,7 @@ int main(int argc, char **argv) /* Initialize testsuite */ testsuite_settings_init(); - sieve_tool_sieve_init(&testsuite_sieve_env, debug); + sieve_tool_init(&testsuite_sieve_env, NULL, debug); sieve_tool_load_plugins(&plugins); sieve_extensions_set_string(sieve_instance, extensions); testsuite_init(sieve_instance, log_stdout);