# HG changeset patch # User Timo Sirainen # Date 1490271582 -7200 # Node ID df29d7876ea55d97ae20564d6665d6983ae21c5d # Parent 869db4bcecdb0b852a3c991fc43eedfc7a5f8d24 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. diff -r 869db4bcecdb -r df29d7876ea5 src/lmtp/commands.c --- a/src/lmtp/commands.c Thu Mar 23 14:15:49 2017 +0200 +++ b/src/lmtp/commands.c Thu Mar 23 14:19:42 2017 +0200 @@ -928,6 +928,11 @@ 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 @@ 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 @@ 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.