From bc72ba681ebc14b5e8384676dc6b74a0abd7840b Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 23 Mar 2017 14:19:42 +0200 Subject: [PATCH] lmtp: Trigger autoexpunging only for the last RCPT TO. Otherwise if the autoexpunging takes a long time, the LMTP client could disconnect due to a timeout. The mails would still eventually get delivered though, so it would result in duplicate mails being delivered. An alternative to this would be to keep all the mail_users referenced until the delivery is finished and then autoexpunge all of them at the end. It increases memory usage though and complicates the code, so at least for now it's not implemented. --- src/lmtp/commands.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/lmtp/commands.c b/src/lmtp/commands.c index a937636648..f0abf29dc8 100644 --- a/src/lmtp/commands.c +++ b/src/lmtp/commands.c @@ -928,6 +928,11 @@ client_deliver(struct client *client, const struct mail_recipient *rcpt, return ret; } +static bool client_rcpt_to_is_last(struct client *client) +{ + return client->state.rcpt_idx >= array_count(&client->state.rcpt_to); +} + static bool client_deliver_next(struct client *client, struct mail *src_mail, struct mail_deliver_session *session) { @@ -947,7 +952,8 @@ static bool client_deliver_next(struct client *client, struct mail *src_mail, return TRUE; /* failed. try the next one. */ if (client->state.dest_user != NULL) { - mail_user_autoexpunge(client->state.dest_user); + if (client_rcpt_to_is_last(client)) + mail_user_autoexpunge(client->state.dest_user); mail_user_unref(&client->state.dest_user); } } @@ -1038,7 +1044,8 @@ client_input_data_write_local(struct client *client, struct istream *input) while (client_deliver_next(client, src_mail, session)) { if (client->state.first_saved_mail == NULL || client->state.first_saved_mail == src_mail) { - mail_user_autoexpunge(client->state.dest_user); + if (client_rcpt_to_is_last(client)) + mail_user_autoexpunge(client->state.dest_user); mail_user_unref(&client->state.dest_user); } else { /* use the first saved message to save it elsewhere too.