]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lmtp: Changed message data handling to use iostream-temp.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 6 Nov 2017 20:54:00 +0000 (21:54 +0100)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Fri, 8 Dec 2017 18:41:03 +0000 (19:41 +0100)
The existing code predates iostream-temp.

src/lmtp/client.c
src/lmtp/client.h
src/lmtp/commands.c

index 06705f9f2d45bbb040d4b5d881736da21de4e0c7..734a5fc43beaf1675981a2a4254b8b86b548c518 100644 (file)
@@ -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,
index d35bfdf2eab9e6e190e55739d907597a984f485d..5d087069db560c860b2b2d16442be783381c73b1 100644 (file)
@@ -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;
index 8a77b5fa7780aa621a0025e0109989c58b6dec6e..a7714bc0ab1fed542985fccdd797bcaa53376982 100644 (file)
@@ -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;