struct smtp_server_cmd_rcpt {
struct smtp_server_recipient *rcpt;
+
+ bool initialized:1;
};
static void
i_assert(smtp_server_command_is_replied(command));
i_assert(conn->state.state == SMTP_SERVER_STATE_RCPT_TO ||
!smtp_server_command_replied_success(command));
+ i_assert(data->initialized);
if (!smtp_server_command_replied_success(command)) {
/* Failure */
struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
{
struct smtp_server_connection *conn = cmd->conn;
+ struct smtp_server_recipient *rcpt = data->rcpt;
i_assert(conn->state.pending_mail_cmds == 0);
+ if (!data->initialized) {
+ smtp_server_recipient_initialize(rcpt);
+ data->initialized = TRUE;
+ }
+
/* All preceeding commands have finished and now the transaction state
is clear. This provides the opportunity to re-check the transaction
state and abort the pending proxied mail command if it is bound to
smtp_server_command_add_hook(command, SMTP_SERVER_COMMAND_HOOK_DESTROY,
cmd_rcpt_destroy, rcpt_data);
+ if (conn->state.trans != NULL) {
+ smtp_server_recipient_initialize(rcpt);
+ rcpt_data->initialized = TRUE;
+ }
+
conn->state.pending_rcpt_cmds++;
smtp_server_command_ref(command);
bool smtp_server_recipient_unref(struct smtp_server_recipient **_rcpt);
void smtp_server_recipient_destroy(struct smtp_server_recipient **_rcpt);
+void smtp_server_recipient_initialize(struct smtp_server_recipient *rcpt);
+
bool smtp_server_recipient_approved(struct smtp_server_recipient **_rcpt);
void smtp_server_recipient_denied(struct smtp_server_recipient *rcpt,
const struct smtp_server_reply *reply);
event, t_strdup_printf("rcpt %s: ", str_sanitize(path, 128)));
}
+static void
+smtp_server_recipient_create_event(struct smtp_server_recipient_private *prcpt)
+{
+ struct smtp_server_recipient *rcpt = &prcpt->rcpt;
+ struct smtp_server_connection *conn = rcpt->conn;
+
+ if (rcpt->event != NULL)
+ return;
+
+ rcpt->event = event_create(conn->event);
+ smtp_server_recipient_update_event(prcpt);
+}
+
struct smtp_server_recipient *
smtp_server_recipient_create(struct smtp_server_cmd_ctx *cmd,
const struct smtp_address *rcpt_to,
prcpt->rcpt.path = smtp_address_clone(pool, rcpt_to);
smtp_params_rcpt_copy(pool, &prcpt->rcpt.params, params);
- prcpt->rcpt.event = event_create(cmd->conn->event);
- smtp_server_recipient_update_event(prcpt);
-
return &prcpt->rcpt;
}
i_unreached();
if (!rcpt->finished) {
+ smtp_server_recipient_create_event(prcpt);
+
struct event_passthrough *e =
event_create_passthrough(rcpt->event)->
set_name("smtp_server_transaction_rcpt_finished");
smtp_server_recipient_unref(_rcpt);
}
+void smtp_server_recipient_initialize(struct smtp_server_recipient *rcpt)
+{
+ struct smtp_server_recipient_private *prcpt =
+ (struct smtp_server_recipient_private *)rcpt;
+
+ smtp_server_recipient_create_event(prcpt);
+}
+
const struct smtp_address *
smtp_server_recipient_get_original(struct smtp_server_recipient *rcpt)
{
struct smtp_server_transaction *trans = rcpt->conn->state.trans;
i_assert(trans != NULL);
+ i_assert(rcpt->event != NULL);
e_debug(rcpt->event, "Approved");
const struct smtp_server_reply *reply)
{
i_assert(!rcpt->finished);
+ i_assert(rcpt->event != NULL);
+
rcpt->finished = TRUE;
struct event_passthrough *e =