From: Timo Sirainen Date: Thu, 8 Oct 2009 21:58:38 +0000 (-0400) Subject: Moved doveadm to a separate directory and made it a bit more easily extensible. X-Git-Tag: 2.0.alpha1~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a6ab8f00351265e35b79f3a22b1f5a4978ae5c35;p=thirdparty%2Fdovecot%2Fcore.git Moved doveadm to a separate directory and made it a bit more easily extensible. --HG-- branch : HEAD --- diff --git a/.hgignore b/.hgignore index 32eb19c770..e8c6a2859f 100644 --- a/.hgignore +++ b/.hgignore @@ -59,6 +59,7 @@ src/config/config src/config/doveconf src/lda/dovecot-lda src/dict/dict +src/doveadm/doveadm src/dsync/dsync src/imap-login/imap-login src/imap/imap @@ -78,7 +79,6 @@ src/plugins/fts-squat/squat-test src/pop3-login/pop3-login src/pop3/pop3 src/util/authtest -src/util/doveadm src/util/dovecotpw src/util/gdbhelper src/util/idxview diff --git a/configure.in b/configure.in index d6a745ebdc..9d8e00a484 100644 --- a/configure.in +++ b/configure.in @@ -2496,6 +2496,7 @@ src/lib-storage/register/Makefile src/anvil/Makefile src/auth/Makefile src/config/Makefile +src/doveadm/Makefile src/dsync/Makefile src/lda/Makefile src/log/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index e9fa43a001..1d3c2ef0c5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,6 +32,7 @@ SUBDIRS = \ log \ config \ util \ + doveadm \ dsync \ ssl-params \ plugins diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am new file mode 100644 index 0000000000..3669720005 --- /dev/null +++ b/src/doveadm/Makefile.am @@ -0,0 +1,25 @@ +bin_PROGRAMS = doveadm + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-auth \ + -I$(top_srcdir)/src/lib-dict \ + -I$(top_srcdir)/src/lib-master \ + -I$(top_srcdir)/src/lib-mail \ + -I$(top_srcdir)/src/lib-imap \ + -I$(top_srcdir)/src/lib-index \ + -I$(top_srcdir)/src/lib-storage \ + -I$(top_srcdir)/src/auth \ + -DPKG_RUNDIR=\""$(rundir)"\" + +doveadm_LDADD = \ + $(LIBDOVECOT_STORAGE) \ + $(LIBDOVECOT) \ + $(MODULE_LIBS) +doveadm_DEPENDENCIES = $(LIBDOVECOT_STORAGE) $(LIBDOVECOT) +doveadm_SOURCES = \ + doveadm.c \ + doveadm-mail.c + +noinst_HEADERS = \ + doveadm-mail.h diff --git a/src/util/doveadm.c b/src/doveadm/doveadm-mail.c similarity index 63% rename from src/util/doveadm.c rename to src/doveadm/doveadm-mail.c index c776f59ed5..8347d15dd3 100644 --- a/src/util/doveadm.c +++ b/src/doveadm/doveadm-mail.c @@ -1,38 +1,25 @@ /* Copyright (c) 2009 Dovecot authors, see the included COPYING file */ #include "lib.h" +#include "array.h" #include "lib-signals.h" #include "ioloop.h" -#include "env-util.h" #include "master-service.h" #include "mail-user.h" #include "mail-namespace.h" #include "mail-storage.h" #include "mail-storage-settings.h" #include "mail-storage-service.h" +#include "doveadm.h" +#include "doveadm-mail.h" #include -#include -static struct mail_user *mail_user; -static int killed_signo = 0; - -static void ATTR_NORETURN -usage(void) -{ - i_fatal( -"usage: doveadm \n" -" purge \n" -" force-resync \n" -); -} +ARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds; -static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED) -{ - killed_signo = si->si_signo; -} +static int killed_signo = 0; -static void cmd_purge(struct mail_user *user) +static void cmd_purge(struct mail_user *user, const char *args[] ATTR_UNUSED) { struct mail_namespace *ns; @@ -68,8 +55,9 @@ mailbox_find_and_open(struct mail_user *user, const char *mailbox) return box; } -static void cmd_force_resync(struct mail_user *user, const char *mailbox) +static void cmd_force_resync(struct mail_user *user, const char *args[]) { + const char *mailbox = args[0]; struct mail_storage *storage; struct mailbox *box; @@ -86,41 +74,34 @@ static void cmd_force_resync(struct mail_user *user, const char *mailbox) mailbox_close(&box); } -static void handle_command(struct mail_user *mail_user, const char *cmd, - char *args[]) -{ - if (strcmp(cmd, "purge") == 0) - cmd_purge(mail_user); - else if (strcmp(cmd, "force-resync") == 0) - cmd_force_resync(mail_user, args[0]); - else - usage(); -} - static void -handle_single_user(struct master_service *service, const char *username, - enum mail_storage_service_flags service_flags, char *argv[]) +doveadm_mail_single_user(doveadm_mail_command_t *cmd, const char *username, + enum mail_storage_service_flags service_flags, + const char *args[]) { struct mail_storage_service_input input; + struct mail_user *mail_user; if (username == NULL) i_fatal("USER environment is missing and -u option not used"); memset(&input, 0, sizeof(input)); input.username = username; - mail_user = mail_storage_service_init_user(service, &input, NULL, + mail_user = mail_storage_service_init_user(master_service, &input, NULL, service_flags); - handle_command(mail_user, argv[0], argv+1); + cmd(mail_user, args); mail_user_unref(&mail_user); mail_storage_service_deinit_user(); } static int -handle_next_user(struct mail_storage_service_multi_ctx *multi, - const struct mail_storage_service_input *input, - pool_t pool, char *argv[]) +doveadm_mail_next_user(doveadm_mail_command_t *cmd, + struct mail_storage_service_multi_ctx *multi, + const struct mail_storage_service_input *input, + pool_t pool, const char *args[]) { struct mail_storage_service_multi_user *multi_user; + struct mail_user *mail_user; const char *error; int ret; @@ -143,14 +124,20 @@ handle_next_user(struct mail_storage_service_multi_ctx *multi, return -1; } mail_storage_service_multi_user_free(multi_user); - handle_command(mail_user, argv[0], argv+1); + cmd(mail_user, args); mail_user_unref(&mail_user); return 0; } +static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED) +{ + killed_signo = si->si_signo; +} + static void -handle_all_users(struct master_service *service, - enum mail_storage_service_flags service_flags, char *argv[]) +doveadm_mail_all_users(doveadm_mail_command_t *cmd, + enum mail_storage_service_flags service_flags, + const char *args[]) { struct mail_storage_service_input input; struct mail_storage_service_multi_ctx *multi; @@ -164,7 +151,8 @@ handle_all_users(struct master_service *service, memset(&input, 0, sizeof(input)); input.service = "doveadm"; - multi = mail_storage_service_multi_init(service, NULL, service_flags); + multi = mail_storage_service_multi_init(master_service, NULL, + service_flags); pool = pool_alloconly_create("multi user", 8192); lib_signals_set_handler(SIGINT, FALSE, sig_die, NULL); @@ -180,7 +168,8 @@ handle_all_users(struct master_service *service, p_clear(pool); input.username = user; T_BEGIN { - ret = handle_next_user(multi, &input, pool, argv); + ret = doveadm_mail_next_user(cmd, multi, &input, + pool, args); } T_END; if (ret < 0) break; @@ -205,28 +194,19 @@ handle_all_users(struct master_service *service, pool_unref(&pool); } -int main(int argc, char *argv[]) +static void +doveadm_mail_cmd(doveadm_mail_command_t *cmd, int argc, char *argv[]) { enum mail_storage_service_flags service_flags = 0; - const char *getopt_str, *username; + const char *username; bool all_users = FALSE; int c; - master_service = master_service_init("doveadm", - MASTER_SERVICE_FLAG_STANDALONE, - argc, argv); - - username = getenv("USER"); - getopt_str = t_strconcat("au:v", master_service_getopt_string(), NULL); - while ((c = getopt(argc, argv, getopt_str)) > 0) { + while ((c = getopt(argc, argv, "av")) > 0) { switch (c) { case 'a': all_users = TRUE; break; - case 'u': - username = optarg; - service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; - break; case 'v': service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG; break; @@ -236,15 +216,65 @@ int main(int argc, char *argv[]) usage(); } } - if (optind == argc) - usage(); - if (!all_users) { - handle_single_user(master_service, username, service_flags, - argv + optind); + if (optind == argc) + usage(); + service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; + username = argv[optind++]; + doveadm_mail_single_user(cmd, username, service_flags, + (const char **)argv + optind); } else { - handle_all_users(master_service, service_flags, argv + optind); + doveadm_mail_all_users(cmd, service_flags, + (const char **)argv + optind); } - master_service_deinit(&master_service); - return 0; +} + +bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[]) +{ + const struct doveadm_mail_cmd *cmd; + + array_foreach(&doveadm_mail_cmds, cmd) { + if (strcmp(cmd->name, cmd_name) == 0) { + doveadm_mail_cmd(cmd->cmd, argc, argv); + return TRUE; + } + } + return FALSE; +} + +void doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd) +{ + /* for now we'll just assume that cmd will be permanently in memory */ + array_append(&doveadm_mail_cmds, cmd, 1); +} + +void doveadm_mail_usage(void) +{ + const struct doveadm_mail_cmd *cmd; + + array_foreach(&doveadm_mail_cmds, cmd) { + fprintf(stderr, " %s |-a", cmd->name); + if (cmd->usage_args != NULL) + fprintf(stderr, " %s", cmd->usage_args); + fputc('\n', stderr); + } +} + +static struct doveadm_mail_cmd mail_commands[] = { + { cmd_purge, "purge", NULL }, + { cmd_force_resync, "force-resync", "" } +}; + +void doveadm_mail_init(void) +{ + unsigned int i; + + i_array_init(&doveadm_mail_cmds, 32); + for (i = 0; i < N_ELEMENTS(mail_commands); i++) + doveadm_mail_register_cmd(&mail_commands[i]); +} + +void doveadm_mail_deinit(void) +{ + array_free(&doveadm_mail_cmds); } diff --git a/src/doveadm/doveadm-mail.h b/src/doveadm/doveadm-mail.h new file mode 100644 index 0000000000..4ac6f1f5a4 --- /dev/null +++ b/src/doveadm/doveadm-mail.h @@ -0,0 +1,25 @@ +#ifndef DOVEADM_MAIL_H +#define DOVEADM_MAIL_H + +struct mail_user; + +typedef void doveadm_mail_command_t(struct mail_user *mail_user, + const char *args[]); + +struct doveadm_mail_cmd { + doveadm_mail_command_t *cmd; + const char *name; + const char *usage_args; +}; +ARRAY_DEFINE_TYPE(doveadm_mail_cmd, struct doveadm_mail_cmd); + +extern ARRAY_TYPE(doveadm_mail_cmd) doveadm_mail_cmds; + +bool doveadm_mail_try_run(const char *cmd_name, int argc, char *argv[]); +void doveadm_mail_register_cmd(const struct doveadm_mail_cmd *cmd); +void doveadm_mail_usage(void); + +void doveadm_mail_init(void); +void doveadm_mail_deinit(void); + +#endif diff --git a/src/doveadm/doveadm.c b/src/doveadm/doveadm.c new file mode 100644 index 0000000000..2f6e292f4a --- /dev/null +++ b/src/doveadm/doveadm.c @@ -0,0 +1,49 @@ +/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "master-service.h" +#include "doveadm-mail.h" +#include "doveadm.h" + +#include +#include +#include + +void usage(void) +{ + fprintf(stderr, "usage: doveadm\n"); + doveadm_mail_usage(); + exit(1); +} + +int main(int argc, char *argv[]) +{ + const char *cmd_name, *getopt_str; + int c; + + master_service = master_service_init("doveadm", + MASTER_SERVICE_FLAG_STANDALONE, + argc, argv); + doveadm_mail_init(); + + /* "+" is GNU extension to stop at the first non-option. + others just accept -+ option. */ + getopt_str = t_strconcat("+", master_service_getopt_string(), NULL); + while ((c = getopt(argc, argv, getopt_str)) > 0) { + if (!master_service_parse_option(master_service, c, optarg)) + usage(); + } + if (optind == argc) + usage(); + + cmd_name = argv[optind]; + argc -= optind; + argv += optind; + + if (!doveadm_mail_try_run(cmd_name, argc, argv)) + usage(); + + master_service_deinit(&master_service); + doveadm_mail_deinit(); + return 0; +} diff --git a/src/doveadm/doveadm.h b/src/doveadm/doveadm.h new file mode 100644 index 0000000000..1ddfa8d852 --- /dev/null +++ b/src/doveadm/doveadm.h @@ -0,0 +1,6 @@ +#ifndef DOVEADM_H +#define DOVEADM_H + +void usage(void); + +#endif diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 34fbc7c25d..fe0aba4ffc 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -12,7 +12,7 @@ pkglibexec_PROGRAMS = \ maildirlock \ threadview -sbin_PROGRAMS = dovecotpw doveadm +sbin_PROGRAMS = dovecotpw AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ @@ -89,11 +89,3 @@ dovecotpw_DEPENDENCIES = $(dovecotpw_libs) dovecotpw_SOURCES = \ dovecotpw.c - -doveadm_LDADD = \ - $(LIBDOVECOT_STORAGE) \ - $(LIBDOVECOT) \ - $(MODULE_LIBS) -doveadm_DEPENDENCIES = $(LIBDOVECOT_STORAGE) $(LIBDOVECOT) -doveadm_SOURCES = \ - doveadm.c