From: Stephan Bosch Date: Mon, 6 Nov 2017 20:54:00 +0000 (+0100) Subject: lmtp: Changed message data handling to use iostream-temp. X-Git-Tag: 2.3.0.rc1~174 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8b2cc4e58aef3759ed071d78afaa8319266afc4;p=thirdparty%2Fdovecot%2Fcore.git lmtp: Changed message data handling to use iostream-temp. The existing code predates iostream-temp. --- diff --git a/src/lmtp/client.c b/src/lmtp/client.c index 06705f9f2d..734a5fc43b 100644 --- a/src/lmtp/client.c +++ b/src/lmtp/client.c @@ -134,7 +134,6 @@ struct client *client_create(int fd_in, int fd_out, bool ssl_start, client->local_port = conn->local_port; client->state_pool = pool_alloconly_create("client state", 4096); - client->state.mail_data_fd = -1; client_read_settings(client); client_raw_user_create(client); @@ -176,13 +175,10 @@ void client_state_reset(struct client *client) if (client->proxy != NULL) lmtp_proxy_deinit(&client->proxy); - buffer_free(&client->state.mail_data); o_stream_unref(&client->state.mail_data_output); - i_close_fd(&client->state.mail_data_fd); i_zero(&client->state); p_clear(client->state_pool); - client->state.mail_data_fd = -1; } void client_destroy(struct client *client, const char *enh_code, diff --git a/src/lmtp/client.h b/src/lmtp/client.h index d35bfdf2ea..5d087069db 100644 --- a/src/lmtp/client.h +++ b/src/lmtp/client.h @@ -21,10 +21,6 @@ struct client_state { struct timeval data_end_timeval; - /* Initially we start writing to mail_data. If it grows too large, - start using mail_data_fd. */ - buffer_t *mail_data; - int mail_data_fd; struct ostream *mail_data_output; const char *added_headers_local; diff --git a/src/lmtp/commands.c b/src/lmtp/commands.c index 8a77b5fa77..a7714bc0ab 100644 --- a/src/lmtp/commands.c +++ b/src/lmtp/commands.c @@ -6,11 +6,11 @@ #include "istream.h" #include "istream-concat.h" #include "ostream.h" -#include "safe-mkstemp.h" -#include "index/raw/raw-storage.h" +#include "iostream-temp.h" #include "master-service.h" #include "settings-parser.h" #include "lda-settings.h" +#include "mail-user.h" #include "lmtp-settings.h" #include "smtp-address.h" #include "smtp-server.h" @@ -70,24 +70,6 @@ int cmd_rcpt(void *conn_ctx, struct smtp_server_cmd_ctx *cmd, * DATA command */ -static struct istream *cmd_data_get_input(struct client *client) -{ - struct client_state *state = &client->state; - struct istream *input; - - if (state->mail_data_output != NULL) { - o_stream_unref(&state->mail_data_output); - input = i_stream_create_fd(state->mail_data_fd, - MAIL_READ_FULL_BLOCK_SIZE); - i_stream_set_init_buffer_size(input, - MAIL_READ_FULL_BLOCK_SIZE); - } else { - input = i_stream_create_from_data(state->mail_data->data, - state->mail_data->used); - } - return input; -} - static void cmd_data_create_added_headers(struct client *client, struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, @@ -112,68 +94,6 @@ cmd_data_create_added_headers(struct client *client, client->state.added_headers_local + proxy_offset; } -static int -cmd_data_input_add_file(struct client *client, - const unsigned char *data, size_t size) -{ - struct client_state *state = &client->state; - string_t *path; - int fd; - - if (state->mail_data_output != NULL) { - /* continue writing to file */ - if (o_stream_send(state->mail_data_output, - data, size) != (ssize_t)size) - return -1; - return 0; - } - - /* move everything to a temporary file. */ - path = t_str_new(256); - mail_user_set_get_temp_prefix(path, client->raw_mail_user->set); - fd = safe_mkstemp_hostpid(path, 0600, (uid_t)-1, (gid_t)-1); - if (fd == -1) { - i_error("Temp file creation to %s failed: %m", str_c(path)); - return -1; - } - - /* we just want the fd, unlink it */ - if (i_unlink(str_c(path)) < 0) { - /* shouldn't happen.. */ - i_close_fd(&fd); - return -1; - } - - state->mail_data_fd = fd; - state->mail_data_output = o_stream_create_fd_file(fd, 0, FALSE); - o_stream_set_name(state->mail_data_output, str_c(path)); - o_stream_cork(state->mail_data_output); - - o_stream_nsend(state->mail_data_output, - state->mail_data->data, state->mail_data->used); - o_stream_nsend(client->state.mail_data_output, data, size); - if (o_stream_flush(client->state.mail_data_output) < 0) { - i_error("write(%s) failed: %s", str_c(path), - o_stream_get_error(client->state.mail_data_output)); - return -1; - } - return 0; -} - -static int -cmd_data_input_add(struct client *client, - const unsigned char *data, size_t size) -{ - if (client->state.mail_data->used + size <= - CLIENT_MAIL_DATA_MAX_INMEMORY_SIZE && - client->state.mail_data_output == NULL) { - buffer_append(client->state.mail_data, data, size); - return 0; - } else { - return cmd_data_input_add_file(client, data, size); - } -} - static int cmd_data_finish(struct client *client, struct smtp_server_cmd_ctx *cmd, @@ -186,7 +106,8 @@ cmd_data_finish(struct client *client, client->state.data_end_timeval = ioloop_timeval; /* finish the message */ - input_msg = cmd_data_get_input(client); + input_msg = iostream_temp_finish(&state->mail_data_output, + IO_BLOCK_SIZE); /* formulate prepended headers for both local and proxy delivery */ cmd_data_create_added_headers(client, cmd, trans); @@ -235,16 +156,21 @@ int cmd_data_continue(void *conn_ctx, struct smtp_server_cmd_ctx *cmd, struct smtp_server_transaction *trans) { struct client *client = (struct client *)conn_ctx; + struct client_state *state = &client->state; struct istream *data_input = (struct istream *)trans->context; const unsigned char *data; size_t size; ssize_t ret; - i_assert(client->state.mail_data_output != NULL); + i_assert(state->mail_data_output != NULL); while ((ret = i_stream_read(data_input)) > 0 || ret == -2) { data = i_stream_get_data(data_input, &size); - if (cmd_data_input_add(client, data, size) < 0) { + if (o_stream_send(state->mail_data_output, + data, size) != (ssize_t)size) { + i_error("write(%s) failed: %s", + o_stream_get_name(state->mail_data_output), + o_stream_get_error(state->mail_data_output)); smtp_server_reply(cmd, 451, "4.3.0", "Temporary internal failure"); return -1; @@ -270,9 +196,14 @@ int cmd_data_begin(void *conn_ctx, struct istream *data_input) { struct client *client = (struct client *)conn_ctx; + string_t *path; + + i_assert(client->state.mail_data_output == NULL); - i_assert(client->state.mail_data == NULL); - client->state.mail_data = buffer_create_dynamic(default_pool, 1024*64); + path = t_str_new(256); + mail_user_set_get_temp_prefix(path, client->raw_mail_user->set); + client->state.mail_data_output = + iostream_temp_create_named(str_c(path), 0, "(lmtp data)"); cmd->context = (void*)client;