]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: client: transaction: Don't call the DATA callbacks upon failure until the...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Fri, 23 Feb 2018 19:43:50 +0000 (20:43 +0100)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Sun, 25 Feb 2018 08:20:24 +0000 (09:20 +0100)
The transaction is not complete until smtp_client_transaction_send() is called.

src/lib-smtp/smtp-client-private.h
src/lib-smtp/smtp-client-transaction.c

index 3775f0f138901843ff96d008c66a884b8b7a96bf..d10aa134bb87936b7d8bb9a8c9852a974195ceba 100644 (file)
@@ -99,6 +99,7 @@ struct smtp_client_transaction {
        unsigned int finish_timeout_msecs;
        struct timeout *to_finish, *to_send;
 
+       bool data_provided:1;
        bool finished:1;
        bool submitted_data:1;
 };
index ca5933c17411f45601a6a9a7e8f072dba73237a6..dc78e6a15a7c8ec372d0a02dedac1ba2f77bd71c 100644 (file)
@@ -356,9 +356,16 @@ void smtp_client_transaction_fail_reply(struct smtp_client_transaction *trans,
                }
        }
 
-       if (trans->cmd_data != NULL)
+       if (!trans->data_provided) {
+               /* smtp_client_transaction_send() was not called yet
+                */
+       } else if (trans->cmd_data != NULL) {
+               /* the DATA command is still pending; handle the failure by
+                  failing the DATA command. */
                smtp_client_command_fail_reply(&trans->cmd_data, reply);
-       else {
+       } else {
+               /* the DATA command was not sent yet; call all DATA callbacks
+                  for the recipients that were previously accepted. */
                rcpts = array_get_modifiable(&trans->rcpts, &count);
                for (i = trans->rcpt_next_data_idx; i < count; i++) {
                        if (rcpts[i]->data_callback != NULL) {
@@ -379,9 +386,9 @@ void smtp_client_transaction_fail_reply(struct smtp_client_transaction *trans,
                smtp_client_command_abort(&trans->cmd_plug);
        trans->cmd_plug = NULL;
 
-       if (trans->data_input != NULL) {
-               /* abort the transaction if it is complete
-                  (if it is not aborted already) */
+       if (trans->data_provided) {
+               /* abort the transaction only if smtp_client_transaction_send()
+                  was called (and if it is not aborted already) */
                smtp_client_transaction_abort(trans);
        }
 
@@ -732,6 +739,8 @@ void smtp_client_transaction_send(
 
        smtp_client_transaction_debug(trans, "Send");
 
+       trans->data_provided = TRUE;
+
        i_assert(trans->data_input == NULL);
        trans->data_input = data_input;
        i_stream_ref(data_input);