diff --git a/src/managesieve/main.c b/src/managesieve/main.c index b7960f5aa96b7d6c7b848c81db8d42f1d3dd36a0..846fac6ba30500dfad6cddd623e7e7ae73394a0c 100644 --- a/src/managesieve/main.c +++ b/src/managesieve/main.c @@ -12,6 +12,7 @@ #include "process-title.h" #include "restrict-access.h" #include "fd-close-on-exec.h" +#include "settings-parser.h" #include "master-interface.h" #include "master-service.h" #include "master-login.h" @@ -128,7 +129,7 @@ client_create_from_input(const struct mail_storage_service_input *input, struct mail_storage_service_user *user; struct mail_user *mail_user; struct client *client; - const struct managesieve_settings *set; + struct managesieve_settings *set; if (mail_storage_service_lookup_next(storage_service, input, &user, &mail_user, error_r) <= 0) @@ -139,6 +140,9 @@ client_create_from_input(const struct mail_storage_service_input *input, if (set->verbose_proctitle) verbose_proctitle = TRUE; + settings_var_expand(&managesieve_setting_parser_info, set, mail_user->pool, + mail_user_var_expand_table(mail_user)); + client = client_create (fd_in, fd_out, input->session_id, mail_user, user, set); T_BEGIN { @@ -195,13 +199,15 @@ login_client_connected(const struct master_login_client *client, client->auth_req.data_size); if (client_create_from_input(&input, client->fd, client->fd, &input_buf, &error) < 0) { - if (write(client->fd, MSG_BYE_INTERNAL_ERROR, + int fd = client->fd; + + if (write(fd, MSG_BYE_INTERNAL_ERROR, strlen(MSG_BYE_INTERNAL_ERROR)) < 0) { if (errno != EAGAIN && errno != EPIPE) i_error("write(client) failed: %m"); } i_error("%s", error); - (void)close(client->fd); + i_close_fd(&fd); master_service_client_connection_destroyed(master_service); } } @@ -276,13 +282,6 @@ int main(int argc, char *argv[]) } } - login_set.auth_socket_path = t_abspath("auth-master"); - if (argv[optind] != NULL) - login_set.postlogin_socket_path = t_abspath(argv[optind]); - login_set.callback = login_client_connected; - login_set.failure_callback = login_client_failed; - - master_service_init_finish(master_service); master_service_set_die_callback(master_service, managesieve_die); /* plugins may want to add commands, so this needs to be called early */ @@ -297,6 +296,7 @@ int main(int argc, char *argv[]) storage_service = mail_storage_service_init(master_service, set_roots, storage_service_flags); + master_service_init_finish(master_service); /* fake that we're running, so we know if client was destroyed while handling its initial input */ @@ -307,6 +307,12 @@ int main(int argc, char *argv[]) main_stdio_run(username); } T_END; } else { + login_set.auth_socket_path = t_abspath("auth-master"); + if (argv[optind] != NULL) + login_set.postlogin_socket_path = t_abspath(argv[optind]); + login_set.callback = login_client_connected; + login_set.failure_callback = login_client_failed; + master_login = master_login_init(master_service, &login_set); io_loop_set_running(current_ioloop); } diff --git a/src/managesieve/managesieve-client.c b/src/managesieve/managesieve-client.c index 0f15a9260cafc2f91593cb9bbac90c14e8561b00..fdb59db5f97a836070d5b3c16d648fc01b74c1f4 100644 --- a/src/managesieve/managesieve-client.c +++ b/src/managesieve/managesieve-client.c @@ -102,11 +102,6 @@ struct client *client_create struct sieve_storage *storage; pool_t pool; - /* Always use nonblocking I/O */ - - net_set_nonblock(fd_in, TRUE); - net_set_nonblock(fd_out, TRUE); - /* Initialize Sieve instance */ memset((void*)&svenv, 0, sizeof(svenv)); @@ -138,9 +133,13 @@ struct client *client_create (fd_in, set->managesieve_max_line_length, FALSE); client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE); + o_stream_set_no_error_handling(client->output, TRUE); + i_stream_set_name(client->input, "<managesieve client>"); + o_stream_set_name(client->output, "<managesieve client>"); + o_stream_set_flush_callback(client->output, client_output, client); - client->io = io_add(fd_in, IO_READ, client_input, client); + client->io = io_add_istream(client->input, client_input, client); client->last_input = ioloop_time; client->parser = managesieve_parser_create (client->input, set->managesieve_max_line_length); @@ -185,7 +184,7 @@ static const char *client_stats(struct client *client) tab = t_malloc(sizeof(static_tab)); memcpy(tab, static_tab, sizeof(static_tab)); - tab[0].value = dec2str(client->input->v_offset); + tab[0].value = dec2str(i_stream_get_absolute_offset(client->input)); tab[1].value = dec2str(client->output->offset); tab[2].value = client->session_id; @@ -249,17 +248,15 @@ void client_destroy(struct client *client, const char *reason) i_stream_destroy(&client->input); o_stream_destroy(&client->output); - if (close(client->fd_in) < 0) - i_error("close(client in) failed: %m"); - if (client->fd_in != client->fd_out) { - if (close(client->fd_out) < 0) - i_error("close(client out) failed: %m"); - } + net_disconnect(client->fd_in); + if (client->fd_in != client->fd_out) + net_disconnect(client->fd_out); sieve_storage_free(client->storage); sieve_deinit(&client->svinst); pool_unref(&client->cmd.pool); + mail_storage_service_user_free(&client->service_user); managesieve_client_count--; DLLIST_REMOVE(&managesieve_clients, client); @@ -269,6 +266,11 @@ void client_destroy(struct client *client, const char *reason) managesieve_refresh_proctitle(); } +static void client_destroy_timeout(struct client *client) +{ + client_destroy(client, NULL); +} + void client_disconnect(struct client *client, const char *reason) { i_assert(reason != NULL); @@ -278,10 +280,15 @@ void client_disconnect(struct client *client, const char *reason) i_info("Disconnected: %s %s", reason, client_stats(client)); client->disconnected = TRUE; - (void)o_stream_flush(client->output); + o_stream_flush(client->output); + o_stream_uncork(client->output); i_stream_close(client->input); o_stream_close(client->output); + + if (client->to_idle != NULL) + timeout_remove(&client->to_idle); + client->to_idle = timeout_add(0, client_destroy_timeout, client); } void client_disconnect_with_error(struct client *client, const char *msg)