From 5fe046cff3d3ddb5a76a7781584b61d97402f94a Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 2 May 2010 10:23:14 +0200 Subject: [PATCH] managesieve: updated to changes in Dovecot (IMAP/POP3). --- src/managesieve/main.c | 56 ++++++++++---------------- src/managesieve/managesieve-client.c | 23 +++++++---- src/managesieve/managesieve-client.h | 2 +- src/managesieve/managesieve-commands.c | 46 +++++++++------------ 4 files changed, 56 insertions(+), 71 deletions(-) diff --git a/src/managesieve/main.c b/src/managesieve/main.c index 7282fa7bf..0e6a3227b 100644 --- a/src/managesieve/main.c +++ b/src/managesieve/main.c @@ -103,37 +103,18 @@ static void managesieve_die(void) static void client_add_input(struct client *client, const buffer_t *buf) { struct ostream *output; - const char *tag; - unsigned int data_pos; - bool send_untagged_capability = FALSE; if (buf != NULL && buf->used > 0) { - tag = t_strndup(buf->data, buf->used); - switch (*tag) { - case '0': - tag++; - break; - case '1': - send_untagged_capability = TRUE; - tag++; - break; - } - data_pos = strlen(tag) + 1; - if (data_pos > buf->used && - !i_stream_add_data(client->input, - CONST_PTR_OFFSET(buf->data, data_pos), - buf->used - data_pos)) + if (!i_stream_add_data(client->input, buf->data, buf->used)) i_panic("Couldn't add client input to stream"); } output = client->output; o_stream_ref(output); o_stream_cork(output); - - client_send_ok(client, "Logged in."); - + if (!IS_STANDALONE()) + client_send_ok(client, "Logged in."); (void)client_input(client); - o_stream_uncork(output); o_stream_unref(&output); } @@ -164,7 +145,7 @@ client_create_from_input(const struct mail_storage_service_input *input, return 0; } -static void main_stdio_run(void) +static void main_stdio_run(const char *username) { struct mail_storage_service_input input; const char *value, *error, *input_base64; @@ -172,7 +153,7 @@ static void main_stdio_run(void) memset(&input, 0, sizeof(input)); input.module = input.service = "managesieve"; - input.username = getenv("USER"); + input.username = username != NULL ? username : getenv("USER"); if (input.username == NULL && IS_STANDALONE()) input.username = getlogin(); if (input.username == NULL) @@ -206,18 +187,13 @@ login_client_connected(const struct master_login_client *client, input.username = username; input.userdb_fields = extra_fields; - if (input.username == NULL) { - i_error("login client: Username missing from auth reply"); - (void)close(client->fd); - return; - } - buffer_create_const_data(&input_buf, client->data, client->auth_req.data_size); if (client_create_from_input(&input, client->fd, client->fd, &input_buf, &error) < 0) { i_error("%s", error); (void)close(client->fd); + master_service_client_connection_destroyed(master_service); } } @@ -250,7 +226,8 @@ int main(int argc, char *argv[]) }; enum master_service_flags service_flags = 0; enum mail_storage_service_flags storage_service_flags = 0; - const char *postlogin_socket_path; + const char *postlogin_socket_path, *username = NULL; + int c; if (IS_STANDALONE() && getuid() == 0 && net_getpeername(1, NULL, NULL) == 0) { @@ -269,9 +246,18 @@ int main(int argc, char *argv[]) } master_service = master_service_init("managesieve", service_flags, - &argc, &argv, NULL); - if (master_getopt(master_service) > 0) - return FATAL_DEFAULT; + &argc, &argv, "u:"); + while ((c = master_getopt(master_service)) > 0) { + switch (c) { + case 'u': + storage_service_flags |= + MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; + username = optarg; + break; + default: + return FATAL_DEFAULT; + } + } postlogin_socket_path = argv[1] == NULL ? NULL : t_abspath(argv[1]); master_service_init_finish(master_service); @@ -290,7 +276,7 @@ int main(int argc, char *argv[]) if (IS_STANDALONE()) { T_BEGIN { - main_stdio_run(); + main_stdio_run(username); } T_END; } else { master_login = master_login_init(master_service, "auth-master", diff --git a/src/managesieve/managesieve-client.c b/src/managesieve/managesieve-client.c index 5b1f38ef3..53941cf3b 100644 --- a/src/managesieve/managesieve-client.c +++ b/src/managesieve/managesieve-client.c @@ -67,8 +67,13 @@ static const struct sieve_environment managesieve_sieve_env = { static void client_idle_timeout(struct client *client) { - client_send_bye(client, "Disconnected for inactivity."); - client_destroy(client, "Disconnected for inactivity"); + if (client->cmd.func != NULL) { + client_destroy(client, + "Disconnected for inactivity in reading our output"); + } else { + client_send_bye(client, "Disconnected for inactivity"); + client_destroy(client, "Disconnected for inactivity"); + } } static struct sieve_storage *client_get_storage @@ -192,7 +197,8 @@ static const char *client_stats(struct client *client) static const char *client_get_disconnect_reason(struct client *client) { - errno = client->input->stream_errno != 0 ? client->input->stream_errno : + errno = client->input->stream_errno != 0 ? + client->input->stream_errno : client->output->stream_errno; return errno == 0 || errno == EPIPE ? "Connection closed" : t_strdup_printf("Connection closed: %m"); @@ -406,22 +412,22 @@ void client_send_storage_error(struct client *client, } bool client_read_args(struct client_command_context *cmd, unsigned int count, - unsigned int flags, struct managesieve_arg **args) + unsigned int flags, struct managesieve_arg **args_r) { int ret; i_assert(count <= INT_MAX); - ret = managesieve_parser_read_args(cmd->client->parser, count, flags, args); + ret = managesieve_parser_read_args(cmd->client->parser, count, flags, args_r); if (ret >= (int)count) { /* all parameters read successfully */ return TRUE; } else if (ret == -2) { /* need more data */ if (cmd->client->input->closed) { - /* disconnected */ - cmd->param_error = TRUE; - } + /* disconnected */ + cmd->param_error = TRUE; + } return FALSE; } else { /* error, or missing arguments */ @@ -565,6 +571,7 @@ static bool client_handle_input(struct client_command_context *cmd) if (cmd->name == NULL) return FALSE; /* need more data */ cmd->name = p_strdup(cmd->pool, cmd->name); + managesieve_refresh_proctitle(); } if (cmd->name == '\0') { diff --git a/src/managesieve/managesieve-client.h b/src/managesieve/managesieve-client.h index d1daa466e..fd904d08c 100644 --- a/src/managesieve/managesieve-client.h +++ b/src/managesieve/managesieve-client.h @@ -112,7 +112,7 @@ void client_send_storage_error(struct client *client, /* Read a number of arguments. Returns TRUE if everything was read or FALSE if either needs more data or error occurred. */ bool client_read_args(struct client_command_context *cmd, unsigned int count, - unsigned int flags, struct managesieve_arg **args); + unsigned int flags, struct managesieve_arg **args_r); /* Reads a number of string arguments. ... is a list of pointers where to store the arguments. */ bool client_read_string_args(struct client_command_context *cmd, diff --git a/src/managesieve/managesieve-commands.c b/src/managesieve/managesieve-commands.c index 4657627c8..585f899a1 100644 --- a/src/managesieve/managesieve-commands.c +++ b/src/managesieve/managesieve-commands.c @@ -13,7 +13,7 @@ * to avoid duplicate code */ -const struct command managesieve_commands[] = { +static const struct command managesieve_base_commands[] = { { "CAPABILITY", cmd_capability }, { "LOGOUT", cmd_logout }, { "PUTSCRIPT", cmd_putscript }, @@ -27,18 +27,19 @@ const struct command managesieve_commands[] = { { "NOOP", cmd_noop } }; -#define MANAGESIEVE_COMMANDS_COUNT N_ELEMENTS(managesieve_commands) +#define MANAGESIEVE_COMMANDS_COUNT N_ELEMENTS(managesieve_base_commands) -static ARRAY_DEFINE(commands, struct command); +static ARRAY_DEFINE(managesieve_commands, struct command); static bool commands_unsorted; void command_register(const char *name, command_func_t *func) { struct command cmd; + memset(&cmd, 0, sizeof(cmd)); cmd.name = name; cmd.func = func; - array_append(&commands, &cmd, 1); + array_append(&managesieve_commands, &cmd, 1); commands_unsorted = TRUE; } @@ -48,10 +49,10 @@ void command_unregister(const char *name) const struct command *cmd; unsigned int i, count; - cmd = array_get(&commands, &count); + cmd = array_get(&managesieve_commands, &count); for (i = 0; i < count; i++) { if (strcasecmp(cmd[i].name, name) == 0) { - array_delete(&commands, i, 1); + array_delete(&managesieve_commands, i, 1); return; } } @@ -62,7 +63,7 @@ void command_unregister(const char *name) void command_register_array(const struct command *cmdarr, unsigned int count) { commands_unsorted = TRUE; - array_append(&commands, cmdarr, count); + array_append(&managesieve_commands, cmdarr, count); } void command_unregister_array(const struct command *cmdarr, unsigned int count) @@ -73,45 +74,36 @@ void command_unregister_array(const struct command *cmdarr, unsigned int count) } } -static int command_cmp(const void *p1, const void *p2) +static int command_cmp(const struct command *c1, const struct command *c2) { - const struct command *c1 = p1, *c2 = p2; - return strcasecmp(c1->name, c2->name); } -static int command_bsearch(const void *name, const void *cmd_p) +static int command_bsearch(const char *name, const struct command *cmd) { - const struct command *cmd = cmd_p; - return strcasecmp(name, cmd->name); } struct command *command_find(const char *name) { - void *base; - unsigned int count; - - base = array_get_modifiable(&commands, &count); - if (commands_unsorted) { - qsort(base, count, sizeof(struct command), command_cmp); - commands_unsorted = FALSE; - } + if (commands_unsorted) { + array_sort(&managesieve_commands, command_cmp); + commands_unsorted = FALSE; + } - return bsearch(name, base, count, sizeof(struct command), - command_bsearch); + return array_bsearch(&managesieve_commands, name, command_bsearch); } void commands_init(void) { - i_array_init(&commands, 16); + i_array_init(&managesieve_commands, 16); commands_unsorted = FALSE; - command_register_array(managesieve_commands, MANAGESIEVE_COMMANDS_COUNT); + command_register_array(managesieve_base_commands, MANAGESIEVE_COMMANDS_COUNT); } void commands_deinit(void) { - command_unregister_array(managesieve_commands, MANAGESIEVE_COMMANDS_COUNT); - array_free(&commands); + command_unregister_array(managesieve_base_commands, MANAGESIEVE_COMMANDS_COUNT); + array_free(&managesieve_commands); } -- GitLab