From 3cc2a33aea3cc8521203d775c405f5db15e37dfd Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Fri, 28 Sep 2018 15:44:55 +0200 Subject: [PATCH] lib-smtp: client: transaction: Add support for pipelining more than a single MAIL command. --- src/lib-smtp/smtp-client-transaction.c | 23 +++++++++++++++++++++++ src/lib-smtp/smtp-client-transaction.h | 21 +++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/lib-smtp/smtp-client-transaction.c b/src/lib-smtp/smtp-client-transaction.c index 92cee021cd..ca8b5b3df0 100644 --- a/src/lib-smtp/smtp-client-transaction.c +++ b/src/lib-smtp/smtp-client-transaction.c @@ -595,6 +595,29 @@ smtp_client_transaction_mail_cb(const struct smtp_reply *reply, } } +#undef smtp_client_transaction_add_mail +void smtp_client_transaction_add_mail( + struct smtp_client_transaction *trans, + const struct smtp_address *mail_from, + const struct smtp_params_mail *mail_params, + smtp_client_command_callback_t *mail_callback, void *context) +{ + struct smtp_client_transaction_mail *mail; + + smtp_client_transaction_debug(trans, "Add MAIL command"); + + i_assert(!trans->data_provided); + i_assert(!trans->reset); + + i_assert(trans->state < SMTP_CLIENT_TRANSACTION_STATE_RCPT_TO); + + mail = smtp_client_transaction_mail_new(trans, mail_from, mail_params); + mail->mail_callback = mail_callback; + mail->context = context; + + smtp_client_transaction_submit(trans, FALSE); +} + static void smtp_client_transaction_connection_ready( struct smtp_client_transaction *trans) { diff --git a/src/lib-smtp/smtp-client-transaction.h b/src/lib-smtp/smtp-client-transaction.h index ecc42b696d..f897f29b5a 100644 --- a/src/lib-smtp/smtp-client-transaction.h +++ b/src/lib-smtp/smtp-client-transaction.h @@ -68,6 +68,27 @@ void smtp_client_transaction_start(struct smtp_client_transaction *trans, context + CALLBACK_TYPECHECK(mail_callback, void (*)( \ const struct smtp_reply *reply, typeof(context)))) +/* Add an extra pipelined MAIL command to the transaction. The mail_callback is + called once the server replies to the MAIL command. This is usually only + useful for forwarding pipelined SMTP transactions, which can involve more + than a single MAIL command (e.g. to have an implicit fallback sender address + in the pipeline when the first one fails). Of course, only one MAIL command + will succeed and therefore error replies for the others will not abort the + transaction. */ +void smtp_client_transaction_add_mail( + struct smtp_client_transaction *trans, + const struct smtp_address *mail_from, + const struct smtp_params_mail *mail_params, + smtp_client_command_callback_t *mail_callback, void *context) + ATTR_NULL(3,5); +#define smtp_client_transaction_add_mail(trans, \ + mail_from, mail_params, mail_callback, context) \ + smtp_client_transaction_add_mail(trans, mail_from + \ + CALLBACK_TYPECHECK(mail_callback, void (*)( \ + const struct smtp_reply *reply, typeof(context))), \ + mail_params, \ + (smtp_client_command_callback_t *)mail_callback, context) + /* Add recipient to the transaction with a RCPT TO command. The rcpt_to_callback is called once the server replies to the RCPT TO command. If RCPT TO succeeded, the data_callback is called once the server replies -- 2.47.3