dovecot-1.3: lmtp: If mail is >128 kB, write it to a temporary f...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Apr 17 19:54:54 EEST 2009
details: http://hg.dovecot.org/dovecot-1.3/rev/a80db92d296b
changeset: 9133:a80db92d296b
user: Timo Sirainen <tss at iki.fi>
date: Fri Apr 17 12:54:49 2009 -0400
description:
lmtp: If mail is >128 kB, write it to a temporary file.
diffstat:
1 file changed, 68 insertions(+), 6 deletions(-)
src/lmtp/commands.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++-----
diffs (115 lines):
diff -r dad05c75bd48 -r a80db92d296b src/lmtp/commands.c
--- a/src/lmtp/commands.c Fri Apr 17 12:54:10 2009 -0400
+++ b/src/lmtp/commands.c Fri Apr 17 12:54:49 2009 -0400
@@ -3,7 +3,10 @@
#include "lib.h"
#include "ioloop.h"
#include "array.h"
+#include "str.h"
#include "istream.h"
+#include "ostream.h"
+#include "safe-mkstemp.h"
#include "mail-storage-service.h"
#include "index/raw/raw-storage.h"
#include "lda-settings.h"
@@ -256,8 +259,14 @@ static int client_open_raw_mail(struct c
struct istream *input;
enum mail_error error;
- input = i_stream_create_from_data(client->state.mail_data->data,
- client->state.mail_data->used);
+ if (client->state.mail_data_output != NULL) {
+ o_stream_unref(&client->state.mail_data_output);
+ input = i_stream_create_fd(client->state.mail_data_fd,
+ MAIL_READ_BLOCK_SIZE, FALSE);
+ } else {
+ input = i_stream_create_from_data(client->state.mail_data->data,
+ client->state.mail_data->used);
+ }
client->state.raw_box = box =
mailbox_open(&raw_storage, "Dovecot Delivery Mail", input,
MAILBOX_OPEN_NO_INDEX_FILES);
@@ -325,10 +334,55 @@ static void client_input_data_finish(str
}
}
-static void
+static int client_input_add_file(struct client *client,
+ const unsigned char *data, size_t size)
+{
+ string_t *path;
+ int fd;
+
+ if (client->state.mail_data_output != NULL) {
+ /* continue writing to file */
+ if (o_stream_send(client->state.mail_data_output,
+ data, size) != (ssize_t)size)
+ return -1;
+ return 0;
+ }
+
+ /* move everything to a temporary file. FIXME: it really shouldn't
+ be in /tmp.. */
+ path = t_str_new(256);
+ str_append(path, "/tmp/dovecot.lmtp.");
+ fd = safe_mkstemp_hostpid(path, 0600, (uid_t)-1, (gid_t)-1);
+ if (fd == -1)
+ return -1;
+
+ /* we just want the fd, unlink it */
+ if (unlink(str_c(path)) < 0) {
+ /* shouldn't happen.. */
+ i_error("unlink(%s) failed: %m", str_c(path));
+ (void)close(fd);
+ return -1;
+ }
+
+ client->state.mail_data_fd = fd;
+ client->state.mail_data_output = o_stream_create_fd_file(fd, 0, FALSE);
+ o_stream_cork(client->state.mail_data_output);
+ if (o_stream_send(client->state.mail_data_output,
+ data, size) != (ssize_t)size)
+ return -1;
+ return 0;
+}
+
+static int
client_input_add(struct client *client, const unsigned char *data, size_t size)
{
- buffer_append(client->state.mail_data, data, size);
+ if (client->state.mail_data->used + size <=
+ CLIENT_MAIL_DATA_MAX_INMEMORY_SIZE) {
+ buffer_append(client->state.mail_data, data, size);
+ return 0;
+ } else {
+ return client_input_add_file(client, data, size);
+ }
}
static void client_input_data_handle(struct client *client)
@@ -353,7 +407,11 @@ static void client_input_data_handle(str
}
} else if (client->state.data_end_idx == DATA_DOT_NEXT_POS) {
/* saw a dot at the beginning of line. drop it. */
- client_input_add(client, data, i-1);
+ if (client_input_add(client, data, i-1) < 0) {
+ client_destroy(client, "451 4.3.0",
+ "Temporary internal failure");
+ return;
+ }
start = i;
client->state.data_end_idx = 0;
} else {
@@ -366,7 +424,11 @@ static void client_input_data_handle(str
rewind = client->state.data_end_idx - DATA_DOT_NEXT_POS + 1;
i -= rewind; size -= rewind;
}
- client_input_add(client, data + start, i-start);
+ if (client_input_add(client, data + start, i-start) < 0) {
+ client_destroy(client, "451 4.3.0",
+ "Temporary internal failure");
+ return;
+ }
i_stream_skip(client->input, skip == 0 ? i : skip);
if (i < size) {
More information about the dovecot-cvs
mailing list